2017-02-16 9 views
2

私は、一連のドキュメントエディタ(スプレッドシートエディタ、テキストドキュメントエディタ、パワーポイントエディタなど)のスキーマを設計しています。編集者はデータベースを共有しますが、いつかは別のデータベースを使用することがあります。各エディタは、各ドキュメントについて多くの共通情報を共有しますが、ドキュメントの種類に応じて、エディタ固有の情報もあります。1対1の関係にINTERLEAVEテーブルを使用する

私の質問は、エディタごとに異なるスキーマの部分を設計しようとしたことに由来します。ドキュメントに関する一般的な情報(IDなど)を保持するDocsテーブルがあるとします。これに加えて、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テーブルに余分な1列の列があるだけです。一つの懸念は、私の提案された構造が明らかではないパフォーマンスや他の意味を持つかもしれないということです。

これは1:1の関係では合理的な構造ですか?ベストプラクティスに関する明確なガイダンスはありますか。

答えて

2

クラウドスパナは、カラムlimitに近づく危険がないと想定して、いずれかのオプションを効率的に処理できます。多くのSQLクエリを実行する予定がある場合、2テーブルアプローチでは複雑になる可能性があります。正式に結合する必要があるためです(ただし、データはインターリーブされるので一般的に効率的です)。 JOINの余分なSQLの複雑さにもかかわらず、これはおそらくよりクリーンなアプローチです。 YMMV。

+2

私はGoogleのCloud Spannerチームのメンバーです。私たちの中には、社内フォーラムの実際の質問に基づいて質問をあらかじめ入力している人もいます。 AFAICT、これは許可されていますが、問題がある場合はお知らせください。 –

+0

これは実際のユーザーからの本当の質問であり、質問と回答はどちらも高品質です。これは素晴らしいリソースです:) –

1

ここでは、interleaving tablesもサポートするCockroachDBについて回答しています。

インタリーブテーブルの背後にあるアイデアは、データがまとめて読み込まれることが多いデータが同じサーバーに配置されるようにデータがレイアウトされているため、トリップ回数が少なくて済みます。パフォーマンスを向上させるツールであり、データモデリングには明白に役立つものではありません。

あなたの例で提案しているように、テーブルを意味のあるようにインターリーブするには、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];

これは、1つの場所で必要なものすべてを提供し、ユーザーがドキュメントの1つをクリックすると、編集中のドキュメントの種類について特定のテーブルを照会することができます。彼らの行動に応じて実際に別のプログラムを開くのです。