跳至內容

結構化查詢語言/示例資料庫結構

來自華夏公益教科書,開放的書籍,開放的世界


首先,資料庫是資料的集合。這些資料按表的形式組織,如示例中的person表所示。此外,DBMS 中還有許多其他型別的物件:檢視、函式、過程、索引、許可權等等。最初我們關注表,並展示其中四個表,它們作為我們華夏公益教科書的基礎。其他型別的物件將在稍後介紹。

我們儘量保持所有內容儘可能簡單。然而,這四個表的極簡集合演示了 1:n 關係以及 n:m 關係。

person表儲存虛構人物的資訊;請參見:建立簡單表.

-- comment lines start with two consecutive minus signs '--'
CREATE TABLE person (
  -- define columns (name / type / default value / nullable)
  id             DECIMAL      NOT NULL,
  firstname      VARCHAR(50)  NOT NULL,
  lastname       VARCHAR(50)  NOT NULL,
  date_of_birth  DATE,
  place_of_birth VARCHAR(50),
  ssn            CHAR(11),
  weight         DECIMAL DEFAULT 0 NOT NULL,
  -- select one of the defined columns as the Primary Key and
  -- guess a meaningfull name for the Primary Key constraint: 'person_pk' may be a good choice 
  CONSTRAINT person_pk PRIMARY KEY (id)
);

contact表儲存一些人物的聯絡資訊。人們可能會考慮將這些聯絡資訊儲存在person表的附加列中:一列用於電子郵件,一列用於 ICQ,等等。我們出於一些重要原因而拒絕了這種做法。

  • 缺失值:許多人並沒有大多數這些聯絡值,或者我們不知道這些值。因此,該表將看起來像一個稀疏矩陣。
  • 多重性:其他人擁有多個電子郵件地址或多個電話號碼。我們是否要定義許多列 email_1、email_2,...?上限是多少?標準 SQL 沒有提供類似於列“值陣列”的東西(一些實現提供了)。
  • 未來擴充套件:總有一天,會有一些今天未知的聯絡型別。那麼我們必須修改該表。

當聯絡資料進入它自己的表時,我們可以以一種簡單的方式處理所有這些情況。唯一特殊的是將人員與他們的聯絡資料聯絡起來。這項任務將由contact表的person_id列來管理。它儲存與分配人員的主鍵相同的值。

一般來說,我們有一個資訊單元(person),它可能擁有多個相同型別(contact)的資訊單元。我們將這種組合關係稱為關係 - 在這種情況下是1:m 關係(也稱為一對多關係)。每當遇到這種情況,我們都會將可能出現多次的值儲存在一個單獨的表中,以及第一個表的 id。

CREATE TABLE contact (
  -- define columns (name / type / default value / nullable)
  id             DECIMAL      NOT NULL,
  person_id      DECIMAL      NOT NULL,
  -- use a default value, if contact_type is omitted
  contact_type   VARCHAR(25)  DEFAULT 'email' NOT NULL,
  contact_value  VARCHAR(50)  NOT NULL,
  -- select one of the defined columns as the Primary Key
  CONSTRAINT contact_pk PRIMARY KEY (id),
  -- define Foreign Key relation between column person_id and column id of table person
  CONSTRAINT contact_fk FOREIGN KEY (person_id) REFERENCES person(id),
  -- more constraint(s)
  CONSTRAINT contact_check CHECK (contact_type IN ('fixed line', 'mobile', 'email', 'icq', 'skype'))
);

人們通常從事一項或多項愛好。關於多重性,我們遇到了與contact表相同的問題。因此,我們需要為愛好建立一個單獨的表。

CREATE TABLE hobby (
  -- define columns (name / type / default value / nullable)
  id             DECIMAL      NOT NULL,
  hobbyname      VARCHAR(100) NOT NULL,
  remark         VARCHAR(1000),
  -- select one of the defined columns as the Primary Key
  CONSTRAINT hobby_pk PRIMARY KEY (id),
  -- forbid duplicate recording of a hobby 
  CONSTRAINT hobby_unique UNIQUE (hobbyname)
);

你可能已經注意到,表中沒有與之對應的列。為什麼?對於愛好,我們還有一個額外的難題:不僅僅是一個人從事多個愛好,同時,多個人從事相同的愛好。

我們將這種組合關係稱為n:m 關係。可以透過在兩個原始表之間建立一個第三張表來設計它。第三張表儲存第一個表和第二個表的 id。因此,人們可以決定哪個人從事哪項愛好。在我們的示例中,這個“中間表”是person_hobby,將在下面定義。

person_hobby

[編輯 | 編輯原始碼]
CREATE TABLE person_hobby (
  -- define columns (name / type / default value / nullable)
  id             DECIMAL      NOT NULL,
  person_id      DECIMAL      NOT NULL,
  hobby_id       DECIMAL      NOT NULL,
  -- Also this table has its own Primary Key!
  CONSTRAINT person_hobby_pk PRIMARY KEY (id),
  -- define Foreign Key relation between column person_id and column id of table person
  CONSTRAINT person_hobby_fk_1 FOREIGN KEY (person_id) REFERENCES person(id),
  -- define Foreign Key relation between column hobby_id and column id of table hobby
  CONSTRAINT person_hobby_fk_2 FOREIGN KEY (hobby_id) REFERENCES hobby(id)
);

該表的每一行都儲存person表中的一個 id 和hobby表中的一個 id。這是將人員和愛好資訊連線在一起的技術。

結構的視覺化

[編輯 | 編輯原始碼]

執行上述命令後,您的資料庫應該包含四個表(沒有任何資料)。表及其彼此之間的關係可以在所謂的實體關係圖中視覺化。左側是personcontact之間的 1:n 關係,右側是personhobby之間的 n:m 關係,以及它的“中間表”person_hobby

我們示例資料庫的視覺表示


華夏公益教科書