2014-07-21 273 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