2009-05-08 68 views
1

我需要构建由3个部分组成的主键。在列中构建并显示复杂的组合主键

  • 第一部分是3个字母长 和必须是一个后跟两个 数字例如“A00”
  • 第二部分是一个3位 唯一标识符包括前导 ZEROES,例如“003”
  • 第三部分是日期的年份部分 ,如“2008”

这一切分离与破折号,所以一个完整的关键看起来像“A00-0 14-2008"

我的解决办法是将与每个数据的三个单独的列,未格式化,然后添加聚集主键约束,当我需要在一个视图中显示它格式化。这是一个好方法吗?我认为可能有一种方法可以使用触发器更新整个密钥,但我不知道如何。另外,我将如何连接并在视图中显示它?

虽然不是一门功课的问题,这将有助于我的学业。

回答

3
CREATE TABLE mytable (
     first TINYINT NOT NULL CHECK(first BETWEEN 0 AND 99), 
     second INT NOT NULL CHECK (second BETWEEN 0 AND 999), 
     third INT NOT NULL, 
     CONSTRAINT pk_mytable_123 PRIMARY KEY (first, second, third) 
    ) 
GO 
CREATE VIEW v_mytable AS 
SELECT 'a' + RIGHT('00' + CAST(first AS VARCHAR), 2) AS first, 
     RIGHT('0000' + CAST(second AS VARCHAR), 4) AS second, 
     third 
FROM mytable 
GO 

INSERT 
INTO mytable 
VALUES (1, 1, 2008) 
GO 

SELECT * 
FROM v_mytable 
GO 

first second third 
---- ---- ---- 
a01 0001 2008 

这个主键只能容纳INT值,所有格式将在视图中进行。

注意,才达到最好的结果在性能方面,你更好地创造,而不是视图计算列,并创建一个额外的UNIQUE指数在这些列:

CREATE TABLE mytable (
     _first TINYINT NOT NULL CHECK(_first BETWEEN 0 AND 99), 
     _second INT NOT NULL CHECK (_second BETWEEN 0 AND 999), 
     third INT NOT NULL, 
     first AS 'a' + RIGHT('00' + CAST(_first AS VARCHAR), 2), 
     second AS RIGHT('0000' + CAST(_second AS VARCHAR), 4) 
     CONSTRAINT pk_mytable_123 PRIMARY KEY (_first, _second, third) 
    ) 

CREATE UNIQUE INDEX ux_mytable_123 ON mytable (first, second, third) 
+0

第二个应该是3个字符长(001而不是0001)并且可能将组合添加到视图中,这似乎是他正在寻找的?又名“a01-001-2008” – Andomar 2009-05-08 11:14:02

+0

似乎他想加入这些价值观从外部世界得到的东西。在这种情况下,最好有3列。连接比分析更容易。 – Quassnoi 2009-05-08 11:15:45

+0

当测试第二个表时,我收到错误,唯一性拼写错误,然后它抱怨语法错误,然后它说“表'mytable2'中的计算列'第二'不允许在另一个计算列定义中使用。 “ – Tarks 2009-05-08 11:24:23

5

我的问题是:自己做任何这三个数值没有意义?或者它们只是主键的组成部分?如果他们完全没有其他的意思,那么你最好只用整个价值创造一个单一的列。

现在“意义”可能很难取得资格。这可能意味着它是一个特定的客户代码或搜索的东西,或者很多东西。

一般来说,我尽量避免组合键,因为它们复杂的连接,通常会让你的生活困难的ORM(通常观看这样的做法 - 无论对错 - 作为“遗产”)。

如果这些领域确实有那么意味着可以说,他们不应该是主键的一部分。我认为这种做法是mistake。我几乎总是使用自动编号列或序列作为主键值(称为“技术键”而不是语义键)。

鉴于用户提供了这部分内容,需要对其进行格式化,所以我假定该密钥具有整体的含义,无论是产品代码,患者代码,预订号码还是其他类似内容。这是正确的吗?

如果是这样,因为我的技术要点(意见在这个问题上有所不同),我会考虑不使这个主键几乎完全偏好。为此创建一个自动编号字段。只需使用varchar(12)或其他任何唯一索引作为acolumn。

+0

+1。尼斯答案 – 2009-05-08 11:03:19

+0

确实很好,谢谢^ _ ^如果我理解你的意思含义,那么不,他们都是为了唯一识别一个记录。我将如何去产生这个?第一部分必须由用户输入,另外两部分由编程生成。 – Tarks 2009-05-08 11:08:53

+0

是的,我很抱歉没有正确的框架问题,整个关键在于识别一名员工。我很乐意将Occam的剃须刀加入此项,并使用自动递增标识列或主键,但需要指明这是与旧系统连接所需的。 – Tarks 2009-05-08 11:22:36

0

主键,通常有两个目的:唯一标识一行,并允许其他数据库表引用它。复合主键完成第一个目的,但是第二个目标很难完成,因为其他表必须引用3列。 ORM系统也是如此,甚至可以从网页进行更新。

最佳实践解决方案是将标识列作为主键。这可以方便地引用该行,并且是所有ORM图层都可以处理的情景。然后,在组成主键的三列上添加一个“唯一”索引。这样你就拥有了两全其美的优点。