Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Cách nhanh nhất để tính toán băm của toàn bộ bảng

Trước hết, tôi nghĩ rằng cách để tiếp cận "quản trị viên lừa đảo" là kết hợp với đường mòn kiểm toán của Oracle và Kho cơ sở dữ liệu các tính năng.

Điều đó nói rằng, đây là những gì tôi có thể thử:

1) Tạo hàm tổng hợp ODCI tùy chỉnh để tính toán băm của nhiều hàng dưới dạng tổng hợp. 2) Tạo VIRTUAL NOT NULL cột trên bảng là hàm băm SHA của tất cả các cột trong bảng - hoặc tất cả cột mà bạn quan tâm bảo vệ. Bạn sẽ giữ điều này mọi lúc - về cơ bản giao dịch loại bỏ một số insert/update/delete đổi lại hiệu suất để có thể tính toán hàm băm nhanh hơn. 3) Tạo chỉ mục không phải là duy nhất trên cột ảo đó4) SELECT my_aggregate_hash_function(virtual_hash_column) FROM my_table để nhận được kết quả.

Đây là mã:

Tạo một hàm tổng hợp để tính toán hàm băm SHA trên một loạt các hàng

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;
/

Tạo một bảng thử nghiệm để làm việc (bạn bỏ qua bước này vì bạn có bảng thực của mình)

create table mattmsi as select * from mtl_system_items where rownum <= 200000;

Tạo một băm cột ảo cho dữ liệu của mỗi hàng. Đảm bảo rằng nó là 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 ;

Tạo chỉ mục trên cột ảo; bằng cách này, bạn có thể tính toán hàm băm của mình bằng cách quét toàn bộ chỉ mục hẹp thay vì quét toàn bộ bảng béo

create index msi_compliance_hash_n1 on mattmsi (compliance_hash);  

Tập hợp tất cả lại với nhau để tính toán hàm băm của bạn

SELECT matt_hash_aggregate(compliance_hash) from (select compliance_hash from mattmsi order by compliance_hash);

Một vài nhận xét:

  1. Tôi nghĩ điều quan trọng là sử dụng hàm băm để tính tổng hợp (thay vì chỉ thực hiện SUM() qua các hàm băm cấp độ hàng, bởi vì kẻ tấn công có thể giả mạo tổng chính xác rất dễ dàng.
  2. Tôi không nghĩ rằng bạn có thể (dễ dàng?) sử dụng truy vấn song song bởi vì điều quan trọng là các hàng được cung cấp cho hàm tổng hợp theo thứ tự không nhất quán, nếu không giá trị băm sẽ thay đổi.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. oracle plsql:cách phân tích cú pháp XML và chèn vào bảng

  2. Oracle:Chuyển đổi địa chỉ IPv4 thành một số?

  3. ORA-29908:thiếu lời gọi chính cho toán tử phụ

  4. Nhận các giá trị từ bảng Oracle DB vào hộp danh sách trong c # / wpf

  5. Oracle - Sử dụng chỉ mục với các tham số tùy chọn