一种在多行中实施唯一性的方法,或者重新设计以使其不必要,这样吗?

问题描述 投票:0回答:1

我正在尝试为“分配给事物的序列号”建模。我想将序列号视为由较小的数字或字符组成的单位-因此,诸如“ AB12CD”的序列号将存储为三元组("AB", 12, "CD") :: (varchar, int, varchar)。序列号可以具有任意数量的组件(尽管可能的值仅在2到6之间),并且这些组件将始终匹配(\d+)|([a-z]+)。这里的目的是帮助诸如“组件N在i和j之间的所有事物”之类的查询,而不必在每一行上进行字符串操作(在某些分隔符上拆分,解析ints,跟踪序数)。

我遇到的问题是,我想在数据库中强制执行序列号唯一性,但是按照我目前的想法,我看不到到达那里的方法。该表是这样的:

thing_id | component | char_part | num_part
------------------------------------------
1        | 1         | "AB"      | null
1        | 2         | null      | 12
2        | 1         | "AB"      | null
2        | 2         | null      | 12

因此在上表中,事物1和事物2在概念上均分配有序列号“ AB12”。具有唯一约束的索引视图可以解决此问题,但是我必须使用CTE来递归地按序添加普通对象,而索引视图中的CTE是不可能的。如果我可以在索引视图中进行CTE,则可以对以下内容建立索引,并对“ SN”应用唯一的约束,这将被违反并且生活会很美好:

thing_id | SN
------------------
1        | "AB12"
2        | "AB12"

是否有为此建议的模式,或强制执行“多行唯一性”的方法?我希望不必手动保持两个表同步(一个带有组合字符串值,一个带有切碎的组件)。

sql-server sql-server-2008-r2
1个回答
0
投票

我从此开始,陷入混乱,最后提出的问题多于答案。对于那个很抱歉。将任何人发布为“外部讨论”可能会帮助您找到解决问题的正确方法。

根据您的发言,我认为这是一个标准化问题。按照这种方式处理,我提出了以下内容,这可能并不是您想要的。沿途留下名字…

CREATE TABLE dbo.Component
 (
    Component   varchar(10)  not null  primary key
 )

表组件中的样本数据:

AB
CD
12
34

(我不确定这与您的char_partnum_part值如何相关;我假设每个组件都有唯一的标识符。如果您对不同类型的组件使用不同的识别码,则您有一个更复杂的问题。)

接下来,表Thing,它是通过Components进行构建/组装的,仍然是它自己的,呃,东西,因此需要它自己的正确规范化的每行一件事表:

CREATE TABLE dbo.Thing
 (
   ThingId  int  not null  identity(1,1)  primary key
 )

样本数据:

1
2
3
4

接下来,什么将事物与组件联系起来?多对多桌子!

CREATE TABLE dbo.ThingComposition
 (
    ThingId     int          not null
   ,Component   varchar(10)  not null
   ,primary key clustered (ThingId, Component)
 )

有数据

1, AB
1, 12
2, AB
2, 23
3, AB
4, CD
4, 12
4, 34

此结构或类似的结构应支持切片要求的搜索

以上数据将产生序列号,例如:

1   AB12
2   AB23
3   AB
4   CD1234

但是,我认为SQL中没有任何合理的*和声明性内容,使您无法在ThingComposition表中包含以下内容:

1, AB
1, 12
5, AB
5, 12

在很大程度上还取决于您如何从基本组件代码构造序列号,这在您的描述中并不清楚。 “ AB12”和“ 12AB”都是有效的序列号吗?还会出现更多问题-随着时间跨多个表添加,更新和删除行时,您如何强制序列号唯一性?如果您有“ AB12”,如果必须一次添加一行,该如何添加“ AB1234”?您是否“构建”事物,然后翻转一点(IsLive)说“完成,现在强制执行唯一性”? (可以完成-过滤后的唯一索引。)序列号(事物中的组件)是否会随时间变化?头脑令人困惑。

我打算建议

CREATE TABLE Thing
 (
   ThingId       int           not null  identity(1,1)  primary key
  ,SerialNumber  varchar(100)  not null  --  enough characters?
 )

在SerialNumber上具有唯一索引,并精心构造了应用程序代码,以使用正确的SerialNumber构造并填充它,但是,是的,这很快变得很复杂。我最终遇到了许多悬而未决的问题,无法回答。希望其他人提出一个更好的主意!

*触发器不合理。不要使用触发器。

© www.soinside.com 2019 - 2024. All rights reserved.