如何创建动态唯一约束

时间:2017-01-12 01:42:26

标签: sql database-design

我有一个由分区ID分区的巨大表。每个分区在其唯一约束中可以具有不同数量的字段。考虑一下这个表:

+----+---------+-------+-----+--+
| id | part_id | name  | age |  |
+----+---------+-------+-----+--+
| 1  | 1       | James | 12  |  |
+----+---------+-------+-----+--+
| 2  | 1       | Mary  | 33  |  |
+----+---------+-------+-----+--+
| 3  | 2       | James | 1   |  |
+----+---------+-------+-----+--+
| 4  | 2       | Mike  | 19  |  |
+----+---------+-------+-----+--+
| 5  | 3       | James | 12  |  |
+----+---------+-------+-----+--+

对于part_id: 1我需要对字段name and age设置唯一约束。 part_id: 2需要name的唯一约束。 part_id: 3需要name的唯一约束。我对任何可以实现此目的的数据库持开放态度。

2 个答案:

答案 0 :(得分:1)

Classic RDBMS旨在使用稳定的架构。这意味着表,列,索引,关系的结构不会经常更改,每个表都有固定数量的具有固定类型的列,并且使它们动态化是困难/低效的。

SQL Server有filtered indexes

因此,您可以为每个分区创建单独的唯一索引。

CREATE UNIQUE NONCLUSTERED INDEX IX_Part1 ON YourTable
(
    name ASC,
    age ASC
)
WHERE (part_id = 1)


CREATE UNIQUE NONCLUSTERED INDEX IX_Part2 ON YourTable
(
    name ASC
)
WHERE (part_id = 2)


CREATE UNIQUE NONCLUSTERED INDEX IX_Part3 ON YourTable
(
    name ASC
)
WHERE (part_id = 3)

这些DDL语句是静态的,part_id的值是硬编码的。 Optimiser能够在具有相同WHERE过滤器的查询中使用此类索引,因此它们不仅可用于强制执行约束。

您始终可以编写一个程序,动态生成CREATE INDEX语句的文本,并通过EXEC / sp_executesql运行。 YourTable上可能会有一些聪明的触发器用于动态创建它,因为表中的数据会发生变化,但最后它将是一些静态CREATE INDEX语句。

您可以提前为part_id的所有可能值创建这些索引,即使表中还没有这样的实际值。

如果您有数千个part_id并且想要创建数千个此类唯一约束,那么您当前的架构可能不太合适。

SQL Server允许每个表最多999个非聚簇索引。请参阅Maximum Capacity Specifications for SQL Server

您是否尝试构建EAV (entity-attribute-value) model的某些变体?

也许有非关系型DBMS允许更大的灵活性,更适合您的任务,但我没有经验。

答案 1 :(得分:0)

在oracle中,下面可以动态创建唯一索引

edi