我正在为一组文档编辑器设计架构(电子表格编辑器,文本文档编辑器,powerpoint编辑器等)。编辑将共享一个数据库,尽管他们有一天可能会使用不同的数据库。每个编辑器都为每个文档共享许多常用信息,但随后 - 根据文档的类型 - 还有编辑器特定的信息。
我的问题来自于尝试设计每个编辑器不同的架构部分。假设将有一个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关系的合理结构吗?是否有关于最佳实践的明确指导?
答案 0 :(得分:2)
Cloud Spanner可以有效地处理任一选项,假设您没有接近列limit的风险。如果您打算进行大量的SQL查询,那么使用双表方法可能会更复杂,因为您将正式需要加入它们(尽管由于数据是交错的,连接通常应该是高效的)。尽管JOIN有额外的SQL复杂性,但这可能是更简洁的方法。 YMMV。
答案 1 :(得分:2)
在这里回答CockroachDB,它也支持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];
这会在一个地方为您提供所需的一切,一旦用户点击其中一个文档,您就可以在特定的表格中查询他们正在编辑的文档类型,这是明智的,因为您&# 39;实际上根据他们的行动开设另一个程序。