2013-12-10 12 views
9

Oracle có kiểu dữ liệu tương tự với SQL Server's RowVersion không?Máy chủ SQL: Tương đương RowVersion trong Oracle

Khi bạn chèn hoặc cập nhật hàng, cột Phiên bản tương ứng (thuộc loại RowVersion) được cập nhật tự động.

MSDN says about RowVersion:

  • Là một kiểu dữ liệu đó cho thấy nhiều tự động tạo, độc đáo nhị phân số trong một cơ sở dữ liệu. rowversion thường được sử dụng như một cơ chế cho các hàng bảng dán phiên bản. Kích thước lưu trữ là 8 byte. Loại dữ liệu hàng đợi chỉ là số gia tăng và không bảo tồn ngày hoặc giờ.

  • Mỗi cơ sở dữ liệu có bộ đếm được tăng cho mỗi lần chèn hoặc hoạt động cập nhật được thực hiện trên bảng có cột hàng đảo ngược trong cơ sở dữ liệu. Bộ đếm này là cơ sở dữ liệu hàng tuần. Điều này theo dõi thời gian tương đối bên trong cơ sở dữ liệu, không phải là thời gian thực có thể được liên kết với đồng hồ. Bảng chỉ có thể có một cột chuyển đổi hàng. Mỗi lần một hàng có cột hàng tuần được sửa đổi hoặc chèn vào, giá trị chuyển đổi hàng tuần của cơ sở dữ liệu tăng dần là được chèn vào cột hàng tuần.

  • Bạn có thể sử dụng cột hàng tuần của một hàng để dễ dàng xác định xem bất kỳ giá trị nào trong hàng đã thay đổi kể từ lần đọc cuối cùng. Nếu bất kỳ thay đổi nào được thực hiện cho hàng, giá trị hàng tuần được cập nhật. Nếu không có thay đổi được thực hiện cho hàng, giá trị đảo ngược giống như khi nó trước đó đã được đọc.

  • Bạn có thể thêm một cột hàng tuần vào bảng để giúp duy trì tính toàn vẹn của của cơ sở dữ liệu khi nhiều người dùng đang cập nhật hàng tại cùng một lúc. Bạn cũng có thể muốn biết có bao nhiêu hàng và hàng nào đã được cập nhật mà không cần truy vấn lại bảng.

Chúng tôi đang thiết kế một mô hình dữ liệu với oracle và muốn sử dụng cột Version để quản lý đồng thời.

Tôi cũng muốn biết liệu có cách nào tốt hơn trong thế giới Oracle hay không.

+0

row_Scn thực hiện điều này. nếu phụ thuộc hàng được bật. http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions142.htm – xQbert

Trả lời

4

Câu trả lời đơn giản là Không - nhưng thật dễ dàng để tự tạo một cột và kích hoạt để thiết lập/cập nhật nó.

Một ví dụ đơn giản cho Oracle 11gR2:

CREATE SEQUENCE global_rowversion_seq; 

ALTER TABLE mytable1 ADD rowversion NUMBER; 

ALTER TABLE mytable2 ADD rowversion NUMBER; 

CREATE TRIGGER mytable1_biu 
    BEFORE INSERT OR UPDATE 
    ON mytable1 
    FOR EACH ROW 
BEGIN 
    :NEW.rowversion := global_rowversion_seq.NEXTVAL; 
END mytable1_biu; 

CREATE TRIGGER mytable2_biu 
    BEFORE INSERT OR UPDATE 
    ON mytable2 
    FOR EACH ROW 
BEGIN 
    :NEW.rowversion := global_rowversion_seq.NEXTVAL; 
END mytable2_biu; 

(Nếu bạn đang ở trên một phiên bản Oracle trước đó, các bài tập trong trigger phải được thực hiện với một truy vấn, ví dụ:

SELECT global_rowversion_seq.NEXTVAL 
    INTO :NEW.rowversion 
    FROM dual; 

Bây giờ, hãy nhớ rằng trong một số trường hợp, thiết kế này có thể có tác động hiệu suất trong các tình huống cực đoan (ví dụ: cơ sở dữ liệu với hoạt động chèn/cập nhật cực cao) do tranh chấp từ tất cả các chèn/cập nhật cơ sở dữ liệu bằng cùng một trình tự. có lẽ sẽ tránh gây ra trong lần đầu tiên đặt anyway.

Tùy thuộc vào cách bạn sử dụng cột hàng tuần, có thể là một ý tưởng hay khi sử dụng một chuỗi riêng biệt cho mỗi bảng thay thế. Điều này có nghĩa là, tất nhiên, sự chuyển đổi hàng đó sẽ không còn là duy nhất toàn cầu - nhưng nếu bạn chỉ quan tâm đến việc so sánh các thay đổi với các hàng trong một bảng, thì điều này sẽ ổn thôi.

Một cách khác là để thúc đẩy truy cập cho mỗi hàng cá nhân - điều này không cần một trình tự và cho phép bạn để phát hiện những thay đổi liên tiếp (nhưng không cho phép so sánh bất kỳ hàng để hàng khác):

ALTER TABLE mytable ADD rowversion NUMBER; 

CREATE TRIGGER mytable_biu 
    BEFORE INSERT OR UPDATE 
    ON mytable 
    FOR EACH ROW 
BEGIN 
    :NEW.rowversion := NVL(:OLD.rowversion, 0) + 1; 
END mytable_biu; 

Mỗi hàng sẽ được chèn với rowversion = 1, sau đó các cập nhật tiếp theo cho hàng đó sẽ tăng lên 2, 3, v.v.

+0

Xin chào, Bạn có vẻ gần hơn với câu trả lời, ff bạn có thể xây dựng thêm về dòng này, nó sẽ là tuyệt vời. Tôi đã cập nhật câu hỏi, vui lòng kiểm tra câu hỏi. Cảm ơn. – Falaque

+0

Cảm ơn bạn đã trả lời. – Falaque

14

Oracle có SCN (Dân số hệ thống thay đổi): http://docs.oracle.com/cd/E11882_01/server.112/e10713/transact.htm#CNCPT039

Một số thay đổi hệ thống (SCN) là một hợp lý, nội bộ tem thời gian được sử dụng bởi cơ sở dữ liệu Oracle. Các sự kiện đặt hàng SCN xảy ra trong cơ sở dữ liệu, cần thiết để đáp ứng các thuộc tính ACID của một giao dịch. Cơ sở dữ liệu Oracle sử dụng các SCN để đánh dấu SCN trước khi tất cả các thay đổi được biết là trên đĩa để khôi phục tránh việc áp dụng lại các công việc không cần thiết. Cơ sở dữ liệu cũng sử dụng các SCN để đánh dấu điểm mà tại đó không tồn tại lại một tập dữ liệu để phục hồi có thể dừng lại.

Các SCN xảy ra theo trình tự tăng đơn điệu.Cơ sở dữ liệu Oracle có thể sử dụng một SCN giống như một đồng hồ vì một SCN quan sát cho biết một điểm logic trong thời gian và các quan sát lặp lại trả về các giá trị bằng hoặc lớn hơn. Nếu một sự kiện có SCN thấp hơn một sự kiện khác, thì sự kiện đó xảy ra tại thời điểm trước đó đối với cơ sở dữ liệu. Một số sự kiện có thể chia sẻ cùng một SCN, có nghĩa là chúng xảy ra cùng một lúc đối với cơ sở dữ liệu.

Mọi giao dịch đều có SCN. Ví dụ, nếu một giao dịch cập nhật một hàng, thì cơ sở dữ liệu sẽ ghi lại SCN mà bản cập nhật này đã xảy ra. Các sửa đổi khác trong giao dịch này có cùng một SCN. Khi một giao dịch cam kết, cơ sở dữ liệu sẽ ghi lại một SCN cho cam kết này.


Sử dụng một pseudocolumn ORA_ROWSCN để kiểm tra hiện SCN hàng:
http://docs.oracle.com/cd/B28359_01/server.111/b28286/pseudocolumns007.htm#SQLRF51145

Một ví dụ:

SELECT ora_rowscn, t.* From test t; 

Demo ->http://www.sqlfiddle.com/#!4/535bc/1
(Trên SQLFiddle cam kết rõ ràng rõ ràng don' t làm việc - trên một cơ sở dữ liệu thực tế mỗi cam kết tăng SCN).


Một ví dụ về một "thực" cơ sở dữ liệu:

CREATE TABLE test(
    id int, 
    value int 
); 

INSERT INTO test VALUES(1,0); 
COMMIT; 
SELECT ora_rowscn, t.* FROM test t; 

ORA_ROWSCN   ID  VALUE 
---------- ---------- ---------- 
    3160728   1   0 

UPDATE test SET value = value + 1 WHERE id = 1; 
COMMIT; 
SELECT ora_rowscn, t.* FROM test t; 

ORA_ROWSCN   ID  VALUE 
---------- ---------- ---------- 
    3161657   1   1 

UPDATE test SET value = value + 1 WHERE id = 1; 
COMMIT; 
SELECT ora_rowscn, t.* FROM test t; 

ORA_ROWSCN   ID  VALUE 
---------- ---------- ---------- 
    3161695   1   2 

Nếu SCN của giao dịch được biết, chúng ta có thể sử dụng một truy vấn hồi tưởng để có được một giá trị quá khứ của hàng:
http://docs.oracle.com/cd/B28359_01/appdev.111/b28424/adfns_flashback.htm#g1026131

Ví dụ:

SELECT t.*, 
     versions_startscn, versions_starttime, 
     versions_endscn, versions_endtime, 
     versions_xid, versions_operation 
FROM test VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE t; 

     ID  VALUE VERSIONS_STARTSCN VERSIONS_STARTTIME VERSIONS_ENDSCN VERSIONS_ENDTIME VERSIONS_XID  VERSIONS_OPERATION 
---------- ---------- ----------------- ------------------- --------------- ------------------- ---------------- ------------------ 
     1   2   3161695 13/12/10 08:19:39          06000300EA070000 U     
     1   1   3161657 13/12/10 08:18:39   3161695 13/12/10 08:19:39 06001200EA070000 U     
     1   0            3161657 13/12/10 08:18:39       


SELECT t.*, 
     versions_startscn, versions_starttime, 
     versions_endscn, versions_endtime, 
     versions_xid, versions_operation 
FROM test VERSIONS BETWEEN SCN 3161657 AND 3161657 t; 

     ID  VALUE VERSIONS_STARTSCN VERSIONS_STARTTIME VERSIONS_ENDSCN VERSIONS_ENDTIME VERSIONS_XID  VERSIONS_OPERATION 
---------- ---------- ----------------- ------------------- --------------- ------------------- ---------------- ------------------ 
     1   1   3161657 13/12/10 08:18:39          06001200EA070000 U        
+0

Cảm ơn câu trả lời hay, nhưng RowVersion là một cột thực tế và được sử dụng cho phiên bản dán cột. Mục đích của ORA_ROWSCN không có vẻ như vậy. Tôi đã cập nhật câu hỏi để cung cấp thêm quan điểm về RowVersion. – Falaque

+1

@Falaque: Không, Oracle không có ** ** chính xác tương đương với cột SQL Server ROWVERSION. Đối với ORA_ROWSCN đồng thời lạc quan được sử dụng. Sẽ rất hữu ích nếu bạn cập nhật câu hỏi của mình để cung cấp thêm quan điểm về lý do bạn muốn ROWVERSION trong Oracle. Nếu bạn đang chuyển một cơ sở dữ liệu từ SQL Server sang Oracle thì bạn cần phải bỏ qua các cột ROWVERSION từ các bảng và sử dụng ORA_ROWSCN trong các truy vấn thay cho bất kỳ cột ROWVERSION nào được đặt tên. Nếu đó là một vấn đề, hãy xem xét nó chỉ là một đỉnh của tảng băng trôi với những thứ như mô hình cách ly giao dịch rất khác nhau hoặc các vấn đề vỏ chuỗi đang được tiếp theo ... –

+0

@TomekSzpakowicz, cảm ơn. Tôi đã cập nhật câu hỏi. – Falaque

Các vấn đề liên quan