如何以规范化方式存储有关数据库中列的元数据?

时间:2013-05-16 00:46:14

标签: sql sql-server foreign-keys

假设我有一个简单的表格,如下所示:

CREATE TABLE [dbo].[Product]
(
    ProductID INT -- PK
   ,ProductName NVARCHAR(100)
   ,ProductDescription NVARCHAR(MAX)
   ,ProductOwner NVARCHAR(50)
   -- Extra fields <snip>
)

我希望能够为[dbo].[Product]中的每一列定义标记,并将它们存储在另一个表中。

我可以引入一个FlagType表来定义可能的标志集:

CREATE TABLE [dbo].[FlagType]
(
    FlagTypeID INT -- PK
   ,FlagTypeName NVARCHAR(50)
)

然后是一个Flag表,它提供列,标志类型和值之间的映射:

CREATE TABLE [dbo].[Flag]
(
    FlagID INT -- PK
   ,FlagTypeID INT -- FK => [dbo].[FlagType] (FlagTypeID)
   ,FlagColumn ??? -- FK
   ,FlagValue BIT
)

我的问题是,如何为上面的FK列定义FlagColumn关系,以便它必须始终引用数据库中的有效列?

我最初的想法是将它作为INFORMATION_SCHEMA.COLUMNS的外键,但是这个表似乎没有我可以引用的主键。

1 个答案:

答案 0 :(得分:1)

数据库架构和数据实际上不应该知道自己 也就是说,您的模型和实现不应该引用它自己的元数据。

如果你想到它就毫无意义

一行中的一列存储一个不可分割的信息,这些信息对于某个唯一的实体(行)具有某种商业含义。该应用程序知道这一点为列添加“标志”意味着您正在存储应用程序应该已知的整个列的信息。

但是,如果你坚持,有一种方法:扩展属性。

这是将元数据附加到列的方法。但它不是关系一致的

CREATE TABLE dbo.foo (bar int);
GO
EXEC sys.sp_addextendedproperty 'Display Label', 'Barbarella', 'SCHEMA', 'dbo', 'TABLE', 'foo', 'COLUMN', 'bar'
EXEC sys.sp_addextendedproperty 'Display Description', '60s scifi movie starring Jane Fonda', 'SCHEMA', 'dbo', 'TABLE', 'foo', 'COLUMN', 'bar'
GO
SELECT EP.name, EP.value FROM sys.extended_properties EP
       WHERE class=1 AND EP.major_id= OBJECT_ID('dbo.foo') AND 
                EP.minor_id = COLUMNPROPERTY(OBJECT_ID('dbo.foo'), 'bar', 'ColumnID')
GO