Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 强制从一个表到任何表的引用完整性_Sql_Sql Server_Database Design - Fatal编程技术网

Sql 强制从一个表到任何表的引用完整性

Sql 强制从一个表到任何表的引用完整性,sql,sql-server,database-design,Sql,Sql Server,Database Design,我有许多表示业务对象的表,例如产品、人员、位置,我想添加一个标记表(如在分类法中) 如何允许将多个标记应用于多种类型的实体,从而允许DBMS强制执行引用完整性,而不需要这样的链接表: CREATE TABLE TagUse ( tagId bigint, productId bigint NULL, personId bigint NULL, locationId bigint NULL, ... whateverId bigint

我有许多表示业务对象的表,例如产品、人员、位置,我想添加一个标记表(如在分类法中)

如何允许将多个标记应用于多种类型的实体,从而允许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
)
我刚刚想到了第三种选择:与其为每个实体拥有单独的
*标记
表,不如将每个实体看作是从“
Taggable
”继承的,然后子表引用该表:

CREATE TABLE Taggable (
    taggableId bigint,
    tagId bigint
)

CREATE TABLE Persons (
    personId bigint,
    ...
    taggableId bigint
)
您可以使用序列对象:

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)
)
Java
C#
等编程语言中,可以调用
Persons
Locations
作为
TaggableObject
的扩展

接下来,您可以将
标记实现为:

CREATE TABLE [Tags] (
    tagId BIGINT IDENTITY(1,1),
    objectId BIGINT
)
尽管像这样的实现的问题是,您必须找出识别
Tags.objectId是什么类型的最佳方法


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

这两种可能性都优于您想要做的事情。因为没有办法使您想要的设计具有引用完整性。坦率地说,这是一个SQL反模式。坦白地说,我更喜欢第二种,但我想到了第三种选择。
CREATE TABLE [Tags] (
    tagId BIGINT IDENTITY(1,1),
    objectId BIGINT
)