練習 39:SQL 創建
譯者:飛龍
自豪地采用谷歌翻譯
當我們談論首字母縮寫“CRUD”時,“C”代表“創建”,它不僅僅意味著創建表。這也意味著將數據插入到表中,并使用表和插入來鏈接表。由于我們需要一些表和一些數據來完成其余的 CRUD(增刪改查),我們開始學習如何在 SQL 中執行最基本的創建操作。
表的創建
我在簡介中說,可以對表內的數據執行“增刪改查”操作。你如何把表放在首要位置?通過對數據庫綱要(Schema)執行 CRUD ,第一個要學習的 SQL 語句是CREATE
:
CREATE TABLE person (
id INTEGER PRIMARY KEY,
first_name TEXT,
last_name TEXT,
age INTEGER
);
你可以將其放在一行中,但是我打算討論每一行,所以寫成了多行。這里是每行所做的事情:
ex1.sql:1
CREATE TABLE
的起始,它提供了表的名稱person
。這個部分之后,之后將你想要的字段放到括號里。
ex1.sql:2
id
列,它用于準確確定每一行。列的格式是NAME TYPE
,并且這里我假設,我需要一個INTEGER
也是PRIMARY KEY
。這樣做告訴 SQLite3 來將其特殊對待。
ex1.sql:3~4
first_name
和last_name
列。它們都是TEXT
。
ex1.sql:5
age
列,只是一個INTEGER
。
ex1.sql:6
使用圓括號結束列的列表,之后是一個分號(;
)。
創建多表的數據庫
創建一個表不是特別實用。我希望你現在創建三個表,你可以在里面儲存數據。
CREATE TABLE person (
id INTEGER PRIMARY KEY,
first_name TEXT,
last_name TEXT,
age INTEGER
);
CREATE TABLE pet (
id INTEGER PRIMARY KEY,
name TEXT,
breed TEXT,
age INTEGER,
dead INTEGER
);
CREATE TABLE person_pet (
person_id INTEGER,
pet_id INTEGER
);
在此文件中,你正在為兩種數據類型制作表,然后將它們與第三個表“鏈接”在一起。人們稱這些“鏈接”表為“關系”,但沒有生命的非常愚蠢的人把所有表都成為“關系”,并且熱衷于使那些想要完成工作的人困惑。在我的書中,具有數據的表是“表”,將表連接在一起的表稱為“關系”。
這里沒有任何新東西,除非你看到person_pet
,你會看到我已經寫了兩列:person_id
和pet_id
。將兩個表鏈接在一起,只是向person_pet
插入一行。它擁有兩行的 ID 列的值,你想要鏈接它們。例如,如果person
包含一行id=20
,pet
有一行id=98
,然后假設這個人擁有這個寵物,你會將person_id=20, pet_id=98
插入到person_pet
關系(表)中。
在接下來的幾個練習中,我們將實際插入這樣的數據。
插入數據
你有了要處理的幾個表,所以現在我讓你使用INSERT
命令,放進去一些數據:
INSERT INTO person (id, first_name, last_name, age)
VALUES (0, "Zed", "Shaw", 37);
INSERT INTO pet (id, name, breed, age, dead)
VALUES (0, "Fluffy", "Unicorn", 1000, 0);
INSERT INTO pet VALUES (1, "Gigantor", "Robot", 1, 1);
在這個文件中,我使用兩種不同形式的INSERT
命令。第一種形式是更明確的風格,最有可能是你應該使用的東西。它指定要插入的列,后跟VALUES
,然后要包括的數據。這兩個列表(列名和值)都在括號內,并以逗號分隔。
第七行的第二個版本是一個縮寫版本,它不指定列,而是依賴于表中的隱式順序。這種形式是危險的,因為你不知道你的語句實際訪問哪一列,并且某些數據庫對列沒有可靠的排序。當你真的很懶惰時,最好只用這種形式。
插入引用數據
在最后一節,你會在表中放滿人和寵物。唯一缺少的東西是,誰擁有什么寵物,這個數據存入person_pet
表,如下所示:
INSERT INTO person_pet (person_id, pet_id) VALUES (0, 0);
INSERT INTO person_pet VALUES (0, 1);
我再次使用顯式格式,然后使用隱式格式。我使用我想要的person
表的行id
(這里是0
),和我想要的pet
表的行id
(同樣,0
是獨角獸,1
是死去的機器人)。然后,我們向person_pet
關系表中插入一行,用于人與寵物之間的每個“連接”。
挑戰練習
- 創建另一個數據庫,但為其它東西創建其他
INTEGER
和TEXT
字段,person
可能擁有它們。 - 在這些表中,我創建了第三個關系表來鏈接它們。你如何擺脫這個關系表
person_pet
,并將這些信息優雅放在person
里面?這個變化暗示了什么? - 如果你可以把一行放入
person_pet
,你是否可以放多行?你如何記錄一個瘋狂的貓女士與 50 只貓? - 為人們可能擁有的汽車創建另一個表,并創建其對應的關系表。
- 在你喜歡的搜索引擎中搜索“sqlite3 數據類型”,然后閱讀 SQLite3 文檔中的數據類型。記錄你可以使用什么類型,以及其他看起來很重要的東西。我們稍后會介紹。
- 插入你自己和你的寵物(或像我這樣的虛擬寵物)。
- 如果將上一個練習中的數據庫更改為沒有
person_pet
表,則使用該模式創建一個新數據庫,并將相同的信息插入到該數據庫中。 - 回顧數據類型列表,并記錄不同類型所需的格式。例如,請注意你有多少種方式來寫入
TEXT
數據。 - 為你和你的寵物添加關系。
- 使用這張表,一只寵物可以被多于一個人擁有嗎?這在邏輯上是可能的嗎?家養的狗如何呢?嚴格來說,家庭中的每個人不是擁有它嗎?
- 考慮上面的東西,并且考慮到你有一個替代設計,將
pet_id
放在pearon
表中,哪種設計更適合這種情況?
深入學習
請閱讀 SQLite3 CREATE
命令的文檔,然后查看盡可能多的其他CREATE
語句。你還應該閱讀 https://sqlite.org/lang_insert.html 上的INSERT
文檔,這應該會引導你閱讀許多其他頁面。