实施从一个表到任何表的引用完整性

时间:2015-01-19 21:55:17

标签: sql sql-server database-design

我有各种表示业务对象的表,例如产品,人员,地点以及我想要添加标签表(如分类标准)。

CREATE TABLE Tags (
    tagId bigint IDENTITY,
    name nvarchar(50)
)

如何允许多个标签以一种允许DBMS强制引用完整性的方式应用于多种类型的实体,而不需要像这样的链接表:

CREATE TABLE TagUse (
    tagId bigint,
    productId bigint NULL,
    personId bigint NULL,
    locationId bigint NULL,
    ...        
    whateverId bigint NULL
)

或者更糟:

CREATE TABLE PersonTags (
    tagId bigint,
    personId bigint
)

CREATE TABLE LocationTags (
    tagId bigint,
    locationId bigint
)

...

CREATE TABLE WhateverTags (
    tagId bigint,
    whateverId bigint
)

我只想到了第三种选择:不是每个实体都有单独的*Tags表,每个实体都可以被认为是继承自" Taggable"然后由子表引用:

CREATE TABLE Taggable (
    taggableId bigint,
    tagId bigint
)

CREATE TABLE Persons (
    personId bigint,
    ...
    taggableId bigint
)

1 个答案:

答案 0 :(得分:1)

可以使用序列对象

CREATE TABLE [TaggableObjects] (
    objectId BIGINT IDENTITY(1,1)
)

CREATE TABLE [Persons] (
    objectId BIGINT, -- referencing Objects.objectId
    name VARCHAR(50)
)

CREATE TABLE [Locations] (
    objectId BIGINT, -- referencing Objects.objectId
    country VARCHAR(50)
)

JavaC#等编程语言中,您只需拨打Persons,将Locations称为TaggableObject的扩展名。

在此之后,您可以将Tags实现为:

CREATE TABLE [Tags] (
    tagId BIGINT IDENTITY(1,1),
    objectId BIGINT
)

虽然像这样的实现的问题是你必须找出确定Tags.objectId类型的最佳方法。

请注意,根据您将使用的引擎,许多人支持某种功能以更轻松地实现序列对象,您可能希望直接使用它。