2017-02-16 2 views
2

Я разрабатываю схему для набора редакторов документов (редактор электронных таблиц, редактор текстовых документов, редактор PowerPoint и т. Д.). Редакторы будут совместно использовать базу данных, хотя иногда они могут использовать отдельные базы данных. Каждый редактор разделяет много общей информации для каждого документа, но затем - в зависимости от типа документа - также есть информация, относящаяся к редактору.Использование таблиц INTERLEAVE для отношений 1 к 1

Мой вопрос связан с попыткой разработать части схемы, которые будут отличаться для каждого редактора. Предположим, что будет таблица Документов, в которой содержится общая информация о документах вообще (скажем, ID). Кроме того, я хочу связать информацию, относящуюся к конкретному редактору, который имеет отношение 1: 1 с записью Doc. Предлагаемый мною схема является:

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? Есть ли какие-то конкретные рекомендации в отношении лучших практик?

ответ

2

Облачный гаечный ключ может эффективно обрабатывать любой вариант, если вы не рискуете приблизиться к колонке limit. Если вы планируете выполнять множество SQL-запросов, они могут быть более сложными с помощью подхода с двумя таблицами, поскольку вам обязательно нужно будет присоединиться к ним (хотя соединения, как правило, будут эффективными, поскольку данные чередуются). Несмотря на дополнительное SQL-осложнение JOIN, это, вероятно, более чистый подход. YMMV.

+2

Я являюсь участником команды Cloud Spanner в Google, и некоторые из нас задают здесь вопросы, основанные на некоторых реальных вопросах из внутренних форумов. AFAICT, это разрешено/рекомендуется, но, пожалуйста, сообщите нам, если это проблема. –

+0

Это настоящие вопросы от реальных пользователей, и вопросы и ответы оба качества. Это прекрасный ресурс :) –

1

Ответ на этот вопрос для 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];

Это даст вам все, что вам нужно в одном месте, и как только пользователь нажмет на один из документов, вы можете запросить конкретную таблицу для типа документа, который они редактируют, что разумно, потому что вы фактически открывая другую программу в зависимости от их действия.

Смежные вопросы