SQL - 約束條件:數據完整性的關鍵
你好,未來的數據魔法師們!我很興奮能夠成為你們在 SQL 約束世界中的引路人。作為一個教學 SQL 超過十年的老師,我可以向你們保證,理解約束條件就像是解鎖數據庫管理中的秘密超能力。那麼,我們來一起深入探討吧!
SQL 約束是什麼?
想像你正在建造一個紙牌房子。每一張紙牌都需要精確放置,否則整個結構可能會倒塌。SQL 約束就像是讓你的數據庫「紙牌房子」穩固站立的規則。它們保證表中的數據遵循特定的規則,以保持準確性和一致性。
為什麼約束條件很重要?
讓我分享一個快速的故事。我曾經有一個學生,為一家寵物店建立了一個數據庫,沒有使用約束條件。有一天,他不小心為一隻小狗輸入了一個負數價格。突然之間,人們得到了領養狗的報酬!這場混亂(但狗們很開心)。這就是為什麼我們需要約束條件——來防止這些既滑稽又麻煩的情況。
SQL 約束:陣容介紹
這裡是我們將要探討的主要 SQL 約束的表格:
約束 | 描述 |
---|---|
NOT NULL | 保證列不能有 NULL 值 |
UNIQUE | 保證列中的所有值都是不同的 |
PRIMARY KEY | NOT NULL 和 UNIQUE 的組合 |
FOREIGN KEY | 保證表之間的引用完整性 |
CHECK | 保證列中的所有值滿足特定條件 |
DEFAULT | 為列設置默認值 |
INDEX | 用於快速創建和從數據庫中检索數據 |
現在,我們來一一解析這些約束。
在 SQL 中創建約束
約束可以在創建表的時候添加,或者稍後使用 ALTER TABLE 語句添加。我們先從為我們想像中的寵物店創建一個簡單的表開始:
CREATE TABLE pets (
id INT NOT NULL PRIMARY KEY,
name VARCHAR(50) NOT NULL,
species VARCHAR(50) NOT NULL,
age INT CHECK (age >= 0),
price DECIMAL(10, 2) NOT NULL CHECK (price > 0),
adoption_date DATE DEFAULT NULL
);
這個簡單的表已經包含了多個約束。讓我們來一一解析它們:
NOT NULL 約束
NOT NULL 約束保證列不能有 NULL 值。在我們的例子中,'id'、'name'、'species' 和 'price' 都是 NOT NULL。這意味著每隻寵物必須填寫這些詳細信息。
name VARCHAR(50) NOT NULL,
UNIQUE 鍵約束
雖然我們在這裡沒有顯式使用 UNIQUE,但它值得一提。UNIQUE 約束保證列中的所有值都是不同的。例如,如果我們想要每隻寵物都有唯一的微晶片編號:
ALTER TABLE pets
ADD COLUMN microchip_number VARCHAR(20) UNIQUE;
DEFAULT 值約束
DEFAULT 約束為列提供了一個默認值,當沒有指定值時。在我們的例子中,'adoption_date' 有一个 DEFAULT 為 NULL,意味著如果沒有提供日期,它將是 NULL。
adoption_date DATE DEFAULT NULL
PRIMARY KEY 約束
PRIMARY KEY 約束唯一標識表中的每條記錄。它結合了 NOT NULL 和 UNIQUE。在我們的表中,'id' 是主鍵:
id INT NOT NULL PRIMARY KEY,
FOREIGN KEY 約束
FOREIGN KEY 約束用於防止會破壞表之間鏈接的操作。讓我們添加一個主人表並將其與我們的寵物表鏈接:
CREATE TABLE owners (
owner_id INT NOT NULL PRIMARY KEY,
name VARCHAR(100) NOT NULL
);
ALTER TABLE pets
ADD COLUMN owner_id INT,
ADD CONSTRAINT fk_owner
FOREIGN KEY (owner_id) REFERENCES owners(owner_id);
現在,你不能添加一個不存在於主人表中的 owner_id 的寵物。這就像確保每隻寵物都有真正的家!
CHECK 值約束
CHECK 約束保證列中的所有值滿足特定條件。在我們的寵物表中,我們用它來確保年齡和價格是正數:
age INT CHECK (age >= 0),
price DECIMAL(10, 2) NOT NULL CHECK (price > 0),
INDEX 約束
雖然不完全是約束,但 INDEX 對數據庫性能至關重要。它們就像書後的索引,幫助 SQL 快速找到數據:
CREATE INDEX idx_species ON pets(species);
這在物種列上創建了一個索引,使得按物種搜索更快。
刪除 SQL 約束
有時候,你可能需要移除一個約束。這樣做的方法如下:
ALTER TABLE pets
DROP CONSTRAINT check_price;
這將移除價格列上的 CHECK 約束。
數據完整性約束:將一切整合起來
所有的這些約束一起工作,以確保數據完整性。它們就像是數據庫的免疫系統,保護它免受不良數據的侵害。讓我們看一個更複雜的例子:
CREATE TABLE adoptions (
adoption_id INT NOT NULL PRIMARY KEY,
pet_id INT NOT NULL,
owner_id INT NOT NULL,
adoption_date DATE DEFAULT CURRENT_DATE,
adoption_fee DECIMAL(10, 2) CHECK (adoption_fee >= 0),
FOREIGN KEY (pet_id) REFERENCES pets(id),
FOREIGN KEY (owner_id) REFERENCES owners(owner_id),
UNIQUE (pet_id, adoption_date)
);
這個表保證:
- 每次領養都有唯一的 ID(PRIMARY KEY)
- 每次領養都與有效的寵物和主人鏈接(FOREIGN KEY)
- 領養費用不能為負(CHECK)
- 如果沒有指定領養日期,則默認為今天(DEFAULT)
- 同一天內一隻寵物不能被領養兩次(UNIQUE 組合)
就这样!你现在已經有了使用 SQL 約束保持數據庫乾淨、一致和無錯誤的充分装备。記住,一個約束良好的數據庫是一個快樂的數據庫。快樂編程,未來的數據大師!
Credits: Image by storyset