跳轉到內容

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

來自華夏公益教科書



rDBMS 提供了將資料放入其儲存的不同方式:來自 CSV 檔案、Excel 檔案、特定產品的二進位制檔案,通過幾個 API 或通往其他資料庫的特殊閘道器,以及其他一些技術。因此,將資料引入我們系統的方法有很多種,但並不標準。由於我們談論的是 SQL,因此我們使用標準化的 INSERT 命令來完成此工作。它在所有系統上都可用。

我們只使用少量資料,因為我們想讓事情變得簡單。有時需要大量行來進行效能測試。為此,我們在本頁末尾展示了一個特殊的 INSERT 命令,它會使您的表指數級增長。

--
-- After we have done a lot of tests we may want to reset the data to its original version.
-- To do so, use the DELETE command. But be aware of Foreign Keys: you may be forced to delete
-- persons at the very end - with DELETE it's just the opposite sequence of tables in comparison to INSERTs.
-- Be careful and don't confuse DELETE with DROP !!
--
-- DELETE FROM person_hobby;
-- DELETE FROM hobby;
-- DELETE FROM contact;
-- DELETE FROM person;
-- COMMIT;

INSERT INTO person VALUES (1,  'Larry',  'Goldstein', DATE'1970-11-20', 'Dallas',        '078-05-1120', 95);
INSERT INTO person VALUES (2,  'Tom',    'Burton',    DATE'1977-01-22', 'Birmingham',    '078-05-1121', 75);
INSERT INTO person VALUES (3,  'Lisa',   'Hamilton',  DATE'1975-12-23', 'Richland',      '078-05-1122', 56);
INSERT INTO person VALUES (4,  'Kim',    'Goldstein', DATE'2011-06-01', 'Shanghai',      '078-05-1123', 11);
INSERT INTO person VALUES (5,  'James',  'de Winter', DATE'1975-12-23', 'San Francisco', '078-05-1124', 75);
INSERT INTO person VALUES (6,  'Elias',  'Baker',     DATE'1939-10-03', 'San Francisco', '078-05-1125', 55);
INSERT INTO person VALUES (7,  'Yorgos', 'Stefanos',  DATE'1975-12-23', 'Athens',        '078-05-1126', 64);
INSERT INTO person VALUES (8,  'John',   'de Winter', DATE'1977-01-22', 'San Francisco', '078-05-1127', 77);
INSERT INTO person VALUES (9,  'Richie', 'Rich',      DATE'1975-12-23', 'Richland',      '078-05-1128', 90);
INSERT INTO person VALUES (10, 'Victor', 'de Winter', DATE'1979-02-28', 'San Francisco', '078-05-1129', 78);
COMMIT;

請注意,DATE 的格式可能取決於您的本地環境。此外,SQLite 對字串到 DATE 的隱式轉換使用不同的語法。

-- SQLite syntax
INSERT INTO person VALUES (1,  'Larry',  'Goldstein', DATE('1970-11-20'), 'Dallas',      '078-05-1120', 95);
...
-- DELETE FROM contact;
-- COMMIT;

INSERT INTO contact VALUES (1,  1,  'fixed line', '555-0100');
INSERT INTO contact VALUES (2,  1,  'email',      'larry.goldstein@acme.xx');
INSERT INTO contact VALUES (3,  1,  'email',      'lg@my_company.xx');
INSERT INTO contact VALUES (4,  1,  'icq',        '12111');
INSERT INTO contact VALUES (5,  4,  'fixed line', '5550101');
INSERT INTO contact VALUES (6,  4,  'mobile',     '10123444444');
INSERT INTO contact VALUES (7,  5,  'email',      'james.dewinter@acme.xx');
INSERT INTO contact VALUES (8,  7,  'fixed line', '+30000000000000');
INSERT INTO contact VALUES (9,  7,  'mobile',     '+30695100000000');
COMMIT;
-- DELETE FROM hobby;
-- COMMIT;

INSERT INTO hobby VALUES (1,  'Painting',
                              'Applying paint, pigment, color or other medium to a surface.');
INSERT INTO hobby VALUES (2,  'Fishing',
                              'Catching fishes.');
INSERT INTO hobby VALUES (3,  'Underwater Diving',
                              'Going underwater with or without breathing apparatus (scuba diving / breath-holding).');
INSERT INTO hobby VALUES (4,  'Chess',
                              'Two players have 16 figures each. They move them on an eight-by-eight grid according to special rules.');
INSERT INTO hobby VALUES (5,  'Literature', 'Reading books.');
INSERT INTO hobby VALUES (6,  'Yoga',
                              'A physical, mental, and spiritual practices which originated in ancient India.');
INSERT INTO hobby VALUES (7,  'Stamp collecting',
                              'Collecting of post stamps and related objects.');
INSERT INTO hobby VALUES (8,  'Astronomy',
                              'Observing astronomical objects such as moons, planets, stars, nebulae, and galaxies.');
INSERT INTO hobby VALUES (9,  'Microscopy',
                              'Observing very small objects using a microscope.');
COMMIT;

person_hobby

[編輯 | 編輯原始碼]
-- DELETE FROM person_hobby;
-- COMMIT;

INSERT INTO person_hobby VALUES (1, 1, 1);
INSERT INTO person_hobby VALUES (2, 1, 4);
INSERT INTO person_hobby VALUES (3, 1, 5);
INSERT INTO person_hobby VALUES (4, 5, 2);
INSERT INTO person_hobby VALUES (5, 5, 3);
INSERT INTO person_hobby VALUES (6, 7, 8);
INSERT INTO person_hobby VALUES (7, 4, 4);
INSERT INTO person_hobby VALUES (8, 9, 8);
INSERT INTO person_hobby VALUES (9, 9, 9);
COMMIT;

對於現實的效能測試,我們需要大量的資料。我們示例資料庫中的幾行資料無法滿足此標準。我們如何生成測試資料並將其儲存在表中?有不同的可能性:儲存過程中的 FOR 迴圈、(偽)遞迴呼叫、以系統特定方式匯入外部資料等等。

由於我們正在處理 SQL,因此我們引入了一個 INSERT 命令,它可以移植到所有 rDBMS。儘管它語法簡單,但功能強大。每次執行時,它都會將行數加倍。假設表中有一行。執行完第一個命令後,表中就會有第二行。乍一看,這聽起來很無聊。但是執行 10 次後,就會有超過一千行,執行 20 次後就會有超過一百萬行,我們懷疑只有少數安裝可以執行超過 30 次。

INSERT INTO person (id,                                firstname, lastname, weight)
SELECT              id + (select max(id) from person), firstname, lastname, weight
FROM        person;
COMMIT;

該命令是一個 INSERT 命令,與一個(子)SELECT 命令結合使用。SELECT 命令檢索表的全部行,因為它沒有 WHERE 子句。這就是行數加倍的原因。強制列 firstnamelastname 保持不變。我們忽略可選列。只有主鍵 id 被計算。新值是舊值加上執行命令時可用的最大 id 的總和。

一些額外的說明

  • max(id) 每執行一次只確定一次!這說明了 rDBMS 的一個重要方面:在概念層面上,資料庫在執行命令之前有一個特定的狀態,在執行命令之後有一個新的狀態。命令是將資料庫從一種狀態轉移到另一種狀態的原子操作 - 它們要麼全部執行,要麼完全不執行!SELECT 和帶有 max(id) 的內部 SELECT 都作用於初始狀態。它們永遠不會看到 INSERT 的結果或中間結果。否則,INSERT 永遠不會結束。
  • 如果我們希望觀察增長的過程,可以在表中新增一列,以儲存每次迭代時的 max(id)。
  • 如果 DBMS 支援 AUTOINCREMENT 列,則可以省略新 id 的計算。
  • 對於效能測試,將一些隨機資料儲存在一列或多列中可能會有所幫助。


華夏公益教科書