2017-02-16 15 views
2

我正在設計一組文檔編輯器(電子表格編輯器,文本文檔編輯器,Powerpoint編輯器等)的模式。編輯們將共享一個數據庫,儘管他們可能會在某一天使用不同的數據庫。每個編輯都會爲每個文檔分享大量的常用信息,但是,根據文檔類型的不同,還有編輯器特定的信息。使用INTERLEAVE表進行1對1關係

我的問題來自於嘗試設計架構中每個編輯器都不相同的部分。假設將會有一個Docs表,它包含關於一般文檔的常見信息(比如ID)。最重要的是,我想將特定於與Doc記錄具有1:1關係的特定編輯器的信息相關聯。我建議的模式是:

CREATE TABLE Docs (
    DocId STRING(MAX) NOT NULL, 
    CreationTime TIMESTAMP NOT NULL, 
    .... 
) PRIMARY KEY (DocId); 

CREATE TABLE SpreadsheetStuff (
    DocId STRING(MAX) NOT NULL, 
    ... spreadsheet-specific information here ... 
) PRIMARY KEY (DocId), 
    INTERLEAVE IN PARENT Docs 
    ON DELETE CASCADE; 

CREATE TABLE TextDocumentStuff (
    DocId STRING(MAX) NOT NULL, 
    ... text-document-specific information here ... 
) PRIMARY KEY (DocId), 
    INTERLEAVE IN PARENT Docs 
    ON DELETE CASCADE; 

我的理由是將公共部分與任何編輯器特定的東西隔離開來。

我不知道這是否是不必要的,因爲編輯可以根據自己的需要更改Docs表格,即使此結構在技術上可行。換句話說,我可以在Docs表中添加大量額外的列,並提供與編輯器相關的信息。一個問題是我提出的結構可能會有不明顯的表現或其他影響。

這是1:1關係的合理結構嗎?有沒有關於最佳實踐的明確指導方式?

回答

2

Cloud Spanner可以有效地處理任一選項,假設您不會冒險靠近列limit。如果您計劃執行大量SQL查詢,那麼使用雙表方法可能會更復雜,因爲您將正式需要加入它們(儘管由於數據是交錯的,因此聯接通常應該是高效的)。儘管JOIN有額外的SQL複雜性,但這可能是更乾淨的方法。因人而異。

+2

我是Google Cloud Spanner團隊的成員,我們中的一些人在此基於來自內部論壇的一些真實問題預先填充問題。 AFAICT,這是允許/鼓勵,但請告訴我們,如果這是一個問題。 –

+0

這些是來自真實用戶的真實問題,問題和答案都是高質量的。這是一個很好的資源:) –

1

在這裏回答蟑螂DB,它也支持interleaving tables

交錯表背後的想法很簡單,因此數據的佈局方式使得經常一起讀取的數據位於同一臺服務器上,這需要更少的行程。它是增強性能的工具,而不是對數據建模明顯有用的工具。

爲了有意義地插入表格,就像您在示例中提出的那樣,您可能需要包含User表格,然後在其中交織Docs。這將增加所有用戶的文檔位於同一臺服務器上的可能性,從而更快地返回所有用戶可用的文檔,只要他們登錄即可。這將是您從交織表中獲得最大優勢的地方(就性能而言)。

但是,您的問題實際上更多的是數據建模,這是您可以使用外鍵關係強制執行的功能。關於這一點的好處是,它也明確要求CockroachDB中的交叉表明確規定了這些關係(它看起來在Cloud Spanner中不是必需的)。

使用你的榜樣模式,這裏的這會是什麼樣的CockroachDB:

CREATE TABLE Users (
    UserId INT PRIMARY KEY, 
    ..., 
); 

CREATE TABLE Docs (
    UserId INT, 
    DocId INT, 
    CreationTime TIMESTAMP NOT NULL, 
    ..., 
    PRIMARY KEY (UserId, DocId), 
    CONSTRAINT fk_Users FOREIGN KEY (UserId) REFERENCES Users 
) INTERLEAVE IN PARENT Users (UserId); 

CREATE TABLE SpreadsheetStuff (
    UserId INT, 
    DocId INT, 
    PRIMARY KEY (UserId, DocId), 
    ... spreadsheet-specific information here ... 
    CONSTRAINT fk_Docs FOREIGN KEY (UserId, DocId) REFERENCES Docs 
) INTERLEAVE IN PARENT Docs (UserId, DocId); 

CREATE TABLE TextDocumentStuff (
    UserId INT, 
    DocId INT, 
    PRIMARY KEY (UserId, DocId), 
    ...text-document-specific information here ... 
    CONSTRAINT fk_Docs FOREIGN KEY (UserId, DocId) REFERENCES Docs 
) INTERLEAVE IN PARENT Docs (UserId, DocId); 

當,查詢用戶登錄你想寫那麼很可能是這樣的:

SELECT * FROM Docs WHERE UserId = [this User's ID];

這會給你在一個地方需要的所有東西,一旦用戶點擊其中一個文檔,你就可以查詢特定的表格來查看他們正在編輯的文檔類型,這是明智的,因爲你實際上根據他們的行爲開放了一個不同的計劃。