2014-07-21 150 views
1

首先,让我只是说我仍然是这个真实世界数据库的小白菜,我希望得到一些灯光摆脱这种情况。SQL数据库关系

我最近把一个基本的asp web应用程序放在一起来管理一个带有两个表的SQL数据库。这些表如下:

密钥表:

KEY_ID Key_desc KEY_NUMBER Key_location ISSUED_BY EMP_ID

EMP表:

EMP_ID Emp_fname emp_lname的 Emp_phone

正如您所见,这些表由emp_id字段链接。但是,如果密钥未分配给员工,密钥表允许emp_id列中的空值。

由于这种情况,我关心数据库中的整体关系,而孤立记录正在成为一个问题。

由于键表允许该列为空值,这是否意味着它不在1NF?

截至目前,该web应用程序通过选择所有记录EMP_ID为空,然后分配一个EMP_ID所选择的按键拉动从密钥表的所有记录分配密钥。

但这种关系只有在密钥具有相关联的员工存在,而且好像必须有一个更好的方式来做到这一点。

这可能是一个有点晚来改变应用程序,所以我或多或少地问了这一点纯粹的好奇心。

我想我可能需要一个指定的键表和未分配的按键表,但我不知道我将如何与当前的数据库字段将它们链接。任何人都可以给我一些建议吗?或者,也许帮助我找出一个更好的方式来连接数据库在一起?

我最关心的是孤立记录

这是类型上的移动,所以请原谅我,如果有错误。编辑:非常感谢那些对此作出回应的人。我得到了比我想象的更多的帮助。稍后我会找出答案,当我找出要采取的路线时。

有人告诉我这是正确的地方问。

+0

是否有从“密钥表”到“Emp表”的外键? –

+0

Mike Sherill:此时唯一的关系是emp_id字段是密钥表中的外键(emp_tbl中的主键)。我无法真正想到将它们连接在一起的更好方法。 – user3860870

+0

'钥匙'是你打开门的东西吗? –

回答

1

另一种方法是创建一个第三个表,需要注意的关键任务。如果一个键未分配,只是不要在该表中放置一行。不要在密钥表中放置emp_id外键。

关于你的问题的意见举例:

CREATE TABLE KeyAssignment (
    key_id INT PRIMARY KEY, 
    emp_id INT NOT NULL, 
    FOREIGN KEY (key_id) REFERENCES keys (key_id), 
    FOREIGN KEY (emp_id) REFERENCES emp (emp_id) 
); 

不需要进行其他的属性,因为这两个键和员工的所有细节都已经存储在其他表所示。

请注意,上表并不完全是多对多表,因为key_id本身就是主键。每个key_id只能有一个(或零)行。如果对于给定的key_id有一行,则emp_id不是NULL,因此必须指定赋值。未分配的键在这个表中没有一行(直到它们被分配)。

至于你的原始设计是否在1NF,是的,大多数人都认为它是。非空Emp_id的值是来自员工域的单个值,这就是1NF所需的值。

SQL有额外的规则,NULL可以被视为任何域的虚拟成员,虽然这个规则是否与关系理论相符是controversial。 C.J. Date认为SQL中NULL的概念与关系理论是不相容的。但E.F.Codd认识到NULL的重要性,以表示行中的成员不适用或未知。

+0

谢谢你。我想添加某种分配表,但不知道我将包括哪些字段。也不涉及现有的两个表格。你能否给我一些可能的作业表的语法例子?或者我可以包括哪些领域?如果我不需要改变设计,我很犹豫,但是对这个问题的任何澄清都会有所帮助。 – user3860870

+0

@ user3860870每个表(基本或查询结果)都包含使某些fill-in-the-blanks语句为true的行。例如“key [k]分配给员工[e]”。查找报表/表格来描述您的应用情况。 NULL从不需要。它使陈述和查询变得复杂。但对于SQL DBMS NULL来说,可以提高性能并简化约束。规范化理论不允许NULL。但是将NULL作为任何列的额外值推理可以推理规范化。但它不像其他值,因为SQL关系和逻辑运算符以不同的方式对待它。 – philipxy

0

我认为你正在寻找的DB设计是类似如下(使用MySQL的语法):

create table Emp(
    Emp_ID int not null auto_increment PRIMARY KEY, 
    LastName varchar(30), 
    FirsName varchar(20), 
    Phone varchar(20) 
); 

create table `Key`(
    Key_id int not null auto_increment PRIMARY KEY, 
    Description varchar(255), 
    Key_number int, 
    Key_location int, -- or your data type for this column 
    Issued_by int -- or your data type for this column 
    Emp_id int, -- foreign key to Emp table 
    FOREIGN KEY (Emp_id) references Emp(Emp_ID) 
    ON DELETE CASCADE -- or RESTRICT/NO ACTION options -- see notes below 
); 

另外三点:

1)您还可以使用Restrict/NO ACTION选项以防止主键行被删除。

2)避免使用保留字为表或列名称,像Key

3)我不喜欢用表名前缀列名, emp_lname的。它是多余的,可读性较差。

编辑 按@Hugh琼斯,我分开ISSUED_BY和EMP_ID列 - 感谢休

+0

我将'issued_by'&'emp_id'作为2个字段 –

+0

现在我更仔细地看,你说得对 - 它们是分开的字段。我会编辑答案。 –

+0

@rob tornambe:就设计而言,这可能是我正在寻找的。我必须提到,我最初并没有创建表格,我只是建立了一个web应用程序来处理现有的表格。我正在考虑重新设计它们,这将会派上用场。我很可能会编辑列名以防止冗余。不熟悉限制/不行动......我必须问,如果我试图从密钥表中删除已分配给员工的密钥,会发生什么情况?......它是否会删除任何内容? – user3860870