सबसे पहले, मुझे लगता है कि "दुष्ट प्रशासकों" से संपर्क करने का तरीका Oracle के ऑडिट ट्रेल के संयोजन के साथ है और डेटाबेस वॉल्ट विशेषताएं।
उस ने कहा, मैं यह कोशिश कर सकता हूं:
1) एक से अधिक पंक्तियों के हैश की गणना करने के लिए एक कस्टम ODCI एग्रीगेट फ़ंक्शन बनाएं। 2) एक VIRTUAL NOT NULL
बनाएं तालिका पर स्तंभ जो तालिका के सभी स्तंभों का SHA हैश था -- या जिसकी आप रक्षा करना चाहते हैं। आप इसे हर समय रखेंगे -- मूल रूप से कुछ insert/update/delete
का व्यापार कर रहे हैं अधिक तेज़ी से हैश की गणना करने में सक्षम होने के बदले में प्रदर्शन। 3) उस वर्चुअल कॉलम पर एक गैर-अद्वितीय अनुक्रमणिका बनाएं 4) SELECT my_aggregate_hash_function(virtual_hash_column) FROM my_table
परिणाम प्राप्त करने के लिए।
यह रहा कोड:
पंक्तियों के समूह पर SHA हैश की गणना करने के लिए एक समग्र फ़ंक्शन बनाएं
CREATE OR REPLACE TYPE matt_hash_aggregate_impl AS OBJECT
(
hash_value RAW(32000),
CONSTRUCTOR FUNCTION matt_hash_aggregate_impl(SELF IN OUT NOCOPY matt_hash_aggregate_impl ) RETURN SELF AS RESULT,
-- Called to initialize a new aggregation context
-- For analytic functions, the aggregation context of the *previous* window is passed in, so we only need to adjust as needed instead
-- of creating the new aggregation context from scratch
STATIC FUNCTION ODCIAggregateInitialize (sctx IN OUT matt_hash_aggregate_impl) RETURN NUMBER,
-- Called when a new data point is added to an aggregation context
MEMBER FUNCTION ODCIAggregateIterate (self IN OUT matt_hash_aggregate_impl, value IN raw ) RETURN NUMBER,
-- Called to return the computed aggragate from an aggregation context
MEMBER FUNCTION ODCIAggregateTerminate (self IN matt_hash_aggregate_impl, returnValue OUT raw, flags IN NUMBER) RETURN NUMBER,
-- Called to merge to two aggregation contexts into one (e.g., merging results of parallel slaves)
MEMBER FUNCTION ODCIAggregateMerge (self IN OUT matt_hash_aggregate_impl, ctx2 IN matt_hash_aggregate_impl) RETURN NUMBER,
-- ODCIAggregateDelete
MEMBER FUNCTION ODCIAggregateDelete(self IN OUT matt_hash_aggregate_impl, value raw) RETURN NUMBER
);
/
CREATE OR REPLACE TYPE BODY matt_hash_aggregate_impl IS
CONSTRUCTOR FUNCTION matt_hash_aggregate_impl(SELF IN OUT NOCOPY matt_hash_aggregate_impl ) RETURN SELF AS RESULT IS
BEGIN
SELF.hash_value := null;
RETURN;
END;
STATIC FUNCTION ODCIAggregateInitialize (sctx IN OUT matt_hash_aggregate_impl) RETURN NUMBER IS
BEGIN
sctx := matt_hash_aggregate_impl ();
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateIterate (self IN OUT matt_hash_aggregate_impl, value IN raw ) RETURN NUMBER IS
BEGIN
IF self.hash_value IS NULL THEN
self.hash_value := dbms_crypto.hash(value, dbms_crypto.hash_sh1);
ELSE
self.hash_value := dbms_crypto.hash(self.hash_value || value, dbms_crypto.hash_sh1);
END IF;
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateTerminate (self IN matt_hash_aggregate_impl, returnValue OUT raw, flags IN NUMBER) RETURN NUMBER IS
BEGIN
returnValue := dbms_crypto.hash(self.hash_value,dbms_crypto.hash_sh1);
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateMerge (self IN OUT matt_hash_aggregate_impl, ctx2 IN matt_hash_aggregate_impl) RETURN NUMBER IS
BEGIN
self.hash_value := dbms_crypto.hash(self.hash_value || ctx2.hash_value, dbms_crypto.hash_sh1);
RETURN ODCIConst.Success;
END;
-- ODCIAggregateDelete
MEMBER FUNCTION ODCIAggregateDelete(self IN OUT matt_hash_aggregate_impl, value raw) RETURN NUMBER IS
BEGIN
raise_application_error(-20001, 'Invalid operation -- hash aggregate function does not support windowing!');
END;
END;
/
CREATE OR REPLACE FUNCTION matt_hash_aggregate ( input raw) RETURN raw
PARALLEL_ENABLE AGGREGATE USING matt_hash_aggregate_impl;
/
साथ काम करने के लिए एक परीक्षण तालिका बनाएं (आप इसे छोड़ दें क्योंकि आपके पास आपकी वास्तविक तालिका है)
create table mattmsi as select * from mtl_system_items where rownum <= 200000;
प्रत्येक पंक्ति के डेटा का वर्चुअल कॉलम हैश बनाएं। सुनिश्चित करें कि यह NOT NULL
है
alter table mattmsi add compliance_hash generated always as ( dbms_crypto.hash(to_clob(inventory_item_id || segment1 || last_update_date || created_by || description), 3 /*dbms_crypto.hash_sh1*/) ) VIRTUAL not null ;
वर्चुअल कॉलम पर एक इंडेक्स बनाएं; इस तरह आप अपने हैश की गणना वसा तालिका के पूर्ण स्कैन के बजाय संकीर्ण सूचकांक के पूर्ण स्कैन के साथ कर सकते हैं
create index msi_compliance_hash_n1 on mattmsi (compliance_hash);
अपने हैश की गणना करने के लिए सभी को एक साथ रखें
SELECT matt_hash_aggregate(compliance_hash) from (select compliance_hash from mattmsi order by compliance_hash);
कुछ टिप्पणियाँ:
- मुझे लगता है कि कुल की गणना करने के लिए हैश का उपयोग करना महत्वपूर्ण है (केवल
SUM()
करने के बजाय) पंक्ति-स्तरीय हैश पर, क्योंकि एक हमलावर बहुत आसानी से सही योग बना सकता है। - मुझे नहीं लगता कि आप (आसानी से?) समानांतर क्वेरी का उपयोग कर सकते हैं क्योंकि यह महत्वपूर्ण है कि पंक्तियों को समवर्ती क्रम में कुल फ़ंक्शन में फीड किया जाए, अन्यथा हैश मान बदल जाएगा।