Дизайн таблицы PostgreSQL - как избежать повторного использования идентификаторов - PullRequest
1 голос
/ 20 августа 2010

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

У меня есть несколько таблиц, каждая из которыхимеет идентификатор функции (или фид).Различные типы объектов имеют разные схемы атрибутов, поэтому мне нужно создать разные таблицы для каждого типа.Однако я хочу убедиться, что фидс уникален для всех типов сущностей.

Если у меня есть три типа сущностей, Entity1 / 2/3, представленные следующими 3 таблицами:

Entity1             Entity2             Entity3
    fid                 fid                 fid
    attribute1          attribute2          attribute3

Как мне убедиться, что в системе нет дублирующихся фидов?

Спасибо!

Ответы [ 3 ]

5 голосов
/ 20 августа 2010

PostgreSQL (и Oracle в этом отношении) используют объекты, называемые последовательностями, для генерации последовательных значений.В отличие от подхода MySQL и SQL Server к генерации последовательных значений, последовательности не привязаны к таблице.Таким образом, вы можете определить одну последовательность ( ссылка на документацию ):

CREATE SEQUENCE your_seq 

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

Чтобы использовать его, любой оператор INSERT должен включать:

NEXTVAL('your_seq')

...в позиции в инструкции INSERT, чтобы заполнить соответствующий столбец.IE:

INSERT INTO entity1
  (fid)
VALUES
  (NEXTVAL('your_seq'))

И, чтобы еще немного автоматизировать это, вы должны установить NEXTVAL('your_seq') в качестве значения по умолчанию для всех таблиц, которые его используют.

0 голосов
/ 20 августа 2010

Звучит так, будто Ватсимото и MkV думают о чем-то похожем: базовая таблица содержит FID, а некоторые конкретные таблицы сущностей наследуются от этого.Ватсимото упомянул, что это не работает ... если вы можете заставить его работать, тогда я согласен с вами обоими, что это правильное решение.И, возможно, имитация его с помощью FK на целочисленных идентификаторах недостаточно тесна, чтобы помочь клиентам Watusimoto назначить два объекта на одну и ту же базу EntityBase.

Потенциальным решением этой проблемы может быть составной ключ с типом объекта.чтобы помочь определить это.Один пример:

EntityTypes     EntityBase     Entity1      Entity2
-------------   ------------   ---------    ---------
TypeName (PK)   EntityID       ID           ID
                EntityType     EntityType   EntityType
                CommonAtts     Attribute1   Attribute2
                FID

Constraints:
-----------------------------------------------------------------
EntityBase:
        PK... lots of options.  Probably PK(EntityID, EntityType)
        UNIQUE(FID)
        FK(EntityType) on EntityTypes(TypeName)
Entity1   :
        PK(ID)  (or PK(ID, EntityID))
        EntityType NOT NULL
        CHECK(EntityType = "Entity1")  (e.g., it is constant)
        FK(EntityType) on EntityTypes(TypeName)
        FK(ID, EntityType) on EntityBase (ID, EntityType)
Entity2   :  <Ditto>

У вас есть много гибкости здесь.Вы можете установить FID для каждого типа.Вы можете сделать EntityID уникальными для каждого типа или уникальными для всех сущностей.Вы могли бы сделать EntityBase иметь идентификатор отдельно от EntityID.Вы могли бы даже сделать EntityType каким-нибудь вычисляемым столбцом или установить его по умолчанию, чтобы вам не приходилось записывать в него значение.

Если это не ваша чашка чая из-за накладных расходов EntityType,тогда я неохотно предлагаю следующее:

Entity1      Entity2           Features
---------    ---------   ...   ----------
ID (PK)      ID (PK)           FID (PK, arbitrary)
Attribute1   Attribute2        Entity1ID (FK)
                               Entity2ID (FK)
                               Entity3ID (FK)

Constraints:
-----------------------------------------------------------------
Features  :
        One and only one EntityID is NOT NULL

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

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

0 голосов
/ 20 августа 2010

Я предлагаю использовать guids для вашего поля fid.Таким образом, вы можете быть уверены, что у вас не будет дубликатов fid, и это будет более элегантно, чем либо (i) поддерживать где-то «самый высокий fid» и запрашивать его каждый раз, когда вы выполняете операцию вставки, либо (ii) помещать код в этопроверяет все ваши фиды во всех ваших таблицах каждый раз, когда вы выполняете операцию вставки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...