讓我們一起來學習 SQL 基礎知識,例如創(chuàng)建表、架構和視圖。
SQL:我們都是這方面的專家嗎?其實都是假裝的,而且多虧了 百度,CSDN等技術分享平臺,我們很多問題都是在這上面找到答案的。結合我們在 90 年代學習如何編碼的豐富經驗,我們對 PHPMyAdmin 和 LAMP 堆棧,集成環(huán)境中的現場工作基本上使我們成為專業(yè)程序員。如何繼續(xù)在你的程序簡歷人生寫下更多簡歷信息?而不是單單的我會某某集成環(huán)境下的開發(fā)?
SQL 的存在時間比我們的職業(yè)生涯還要長,那么為什么現在要開始一個關于它的系列呢?當然有足夠多的文檔供我們在需要編寫查詢時通過 百度、360、Bing、Google 搜索具體信息嗎?我的朋友們,這正是問題所在。無論我們擁有什么可用的工具,有些技能最好還是熟記于心地學習和練習。SQL 就是其中一項技能。
當然,SQLAlchemy 或類似的 ORM 可能會保護我們不時地編寫原始查詢。考慮到 SQL 只是我們經常使用的眾多查詢語言之一(除了 NoSQL、GraphQL、JQL 等),成為 SQL 專家真的那么重要嗎?簡而言之,是的:關系數據庫不僅會繼續(xù)存在,而且將查詢作為第二語言進行思考可以鞏固人們對數據細節(jié)的理解。Marc Laforet最近發(fā)表了一篇 Medium 文章,其中闡述了依賴 SQL 的重要性:
更有趣的是,當這些轉換腳本應用于 6.5 GB 數據集時,python 完全失敗了。在 3 次嘗試中,Python 崩潰了 2 次,而我的計算機在第 3 次完全死機……而 SQL 花了 226 秒。
將邏輯排除在我們的應用程序、管道以及 SQL 之外可以使執(zhí)行速度呈指數級增長,同時比我們用我們選擇的語言編寫的任何內容都更具可讀性和普遍理解性。我們可以將應用程序邏輯推送到堆棧中的位置越低越好。這就是為什么我更愿意看到數據領域充斥著 SQL 教程,而不是 Pandas 教程。
關系數據庫術語
我討厭信息材料一開始就涵蓋明顯的術語定義。一般情況下,我覺得這是陳詞濫調,毫無幫助,而且有損作者的可信度;但這些都不是正常情況。在 SQL 中,詞匯通常具有多種含義,具體取決于上下文,甚至取決于您使用的數據庫類型。鑒于這一事實,個人完全有可能(并且很常見)積累關系數據庫的經驗,同時完全誤解基本概念。讓我們確保不會發(fā)生這種情況:
數據庫:每個數據庫實例都在最高級別上分為數據庫。是的,數據庫是數據庫的集合 - 我們已經有了一個良好的開端。
模式:在 PostgreSQL(和其他數據庫)中,模式是表和其他對象的分組,包括視圖、關系等。模式是組織數據的一種方式。模式意味著屬于它的所有數據都以某種形式相關,即使只是概念上相關。請注意,術語模式有時根據上下文用于描述其他概念。
表:關系數據庫的主要部分。表格由行和列組成,其中保存著我們的甜蜜數據。列最好被視為“屬性”,而行是由所述屬性的值組成的條目。列中的所有值必須共享相同的數據類型。
主鍵:每行數據的標識標簽。關系數據庫中每條記錄的主鍵都是不同的;必須提供值,并且它們在行之間必須是唯一的。
外鍵:啟用主數據庫表和其他相關數據庫之間的數據搜索和操作。
鍵:鍵用于幫助我們組織和優(yōu)化數據,并對傳入的數據施加某些限制(例如,用戶帳戶的電子郵件地址必須是唯一的)。鍵還可以幫助我們記錄條目的數量,確保自動唯一的值,并提供鏈接多個數據表的橋梁。
對象:模式(某種程度上特定于 PostgreSQL)中存在的任何事物(包括關系)的總稱。
視圖(PostgreSQL):視圖以類似于表的方式顯示數據,不同之處在于視圖不存儲數據。視圖是以查詢的形式從其他表中提取數據的快照;考慮視圖的一個好方法是將它們視為“虛擬表”。
函數 (PostgreSQL):與為了重用而保存的數據進行交互的邏輯。
在 MySQL 中,模式與數據庫同義。這些關鍵字甚至可以在 MySQL 中互換使用 SCHEMA 和 DATABASE。因此,使用CREATE SCHEMA可以達到與 代替 相同的效果CREATE DATABASE。
導航和創(chuàng)建數據庫
我們必須從某個地方開始,所以最好從數據庫管理開始。誠然,這將是我們將要介紹的內容中最無用的。瀏覽數據庫的行為最適合 GUI。
顯示數據庫
如果您通過命令行 shell 訪問數據庫(出于某種原因),第一個合乎邏輯的事情就是列出可用的數據庫:
SHOW DATABASES; +--------------------+ | Database | +--------------------+ | classicmodels | | information_schema| | mysql | | performance_schema| | sys | +--------------------+ 5 rows in set (0.00 sec)
使用數據庫
現在我們已經列出了可以連接的可能數據庫,我們可以探索每個數據庫包含的內容。為此,我們必須指定要連接到哪個數據庫,也稱為“使用”。
db> USE database_name; Database changed
創(chuàng)建數據庫
創(chuàng)建數據庫很簡單。創(chuàng)建數據庫時一定要注意字符集:這將決定您的數據庫能夠接受哪些類型的字符。例如,如果我們嘗試將特殊編碼字符插入到簡單的 UTF-8 數據庫中,這些字符將不會按照我們的預期顯示。
CREATE DATABASE IF NOT EXISTS database_name CHARACTER SET utf-8 [COLLATE collation_name]
獎勵:這是創(chuàng)建數據庫然后顯示結果的簡寫:
SHOW CREATE DATABASE database_name;
創(chuàng)建和修改表
在自動化數據導入時,通過 SQL 語法創(chuàng)建表非常重要。創(chuàng)建表時,我們還設置列名、類型和鍵:
CREATE TABLE [IF NOT EXISTS] table_name ( column_name_1 [COLUMN_DATA_TYPE] [KEY_TYPE] [KEY_ATTRIBUTES] DEFAULT [DEFAULT_VALUE], column_name_2 [COLUMN_DATA_TYPE] [KEY_TYPE] [KEY_ATTRIBUTES] DEFAULT [DEFAULT_VALUE], PRIMARY KEY (column_name_1) ) ENGINE=[ENGINE_TYPE];
我們可以在創(chuàng)建表時指定IF NOT EXISTS是否要在查詢中包含驗證。如果存在,則僅當指定名稱的表不存在時才會創(chuàng)建該表。
創(chuàng)建每個列時,我們可以為每個列指定許多內容:
數據類型(必填):該列單元格可以保存的數據(如INTEGER、TEXT等)。
鍵類型:為列創(chuàng)建鍵。
鍵屬性:任何與鍵相關的屬性,例如自動遞增。
默認值:如果在表中創(chuàng)建行時沒有將值傳遞到當前列,則該值指定為DEFAULT
主鍵:允許將之前指定的任何列設置為表的主鍵。
MySQL表可以有一個通過指定的“存儲引擎” ENGINE=[engine_type],它決定了表如何解釋數據的核心邏輯。將此字段留空默認為 InnoDB,并且?guī)缀蹩梢钥隙ú挥霉芩?。如果您有興趣,可以在這里(https://dev.mysql.com/doc/refman/8.0/en/storage-engines.html?ref=hackersandslackers.com)找到有關 MySQL 引擎的更多信息。
下面是實際查詢的示例CREATE TABLE:
CREATE TABLE IF NOT EXISTS awards ( id INTEGER PRIMARY KEY AUTO_INCREMENT, recipient TEXT NOT NULL, award_name TEXT DEFAULT 'Grammy', PRIMARY KEY (id) ) ENGINE=INNODB;
管理現有表的鍵
如果我們在創(chuàng)建表時沒有指定鍵,我們總是可以在事后指定鍵。SQL 表可以接受以下鍵類型:
主鍵:唯一標識表中一條記錄的一個或多個字段/列。它不能接受空值、重復值。
候選鍵:候選鍵類似于一組未提交的主鍵;這些鍵只接受唯一值,并且如果需要的話可以用來代替主鍵,但不是實際的主鍵。與主鍵不同,每個表可能存在多個候選鍵。
備用鍵:指單個候選鍵(可以滿足主鍵 id 需要的替代值)。
Composite/Compound Key:通過組合多個列的值來定義;它們的總和總會產生一個獨特的價值。一張表中可以有多個候選鍵。每個候選鍵都可以作為主鍵。
唯一鍵:表的一組一個或多個字段/列,唯一標識數據庫表中的記錄。與主鍵類似,但只能接受一個空值,并且不能有重復值。
外鍵:外鍵表示充當另一個表的主鍵的字段。外鍵對于建立表之間的關系很有用。雖然作為主表的父表中需要外鍵,但在與其他表相關的表中,外鍵可以為 null 或為空。
讓我們看一個示例查詢,其中我們向表添加一個鍵并剖析各個部分:
ALTER TABLE table_name ADD FOREIGN KEY foreign_key_name (column_name) REFERENCES parent_table(columns) ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT }
ALTER TABLE用于對表結構進行任何更改,無論是修改列還是鍵。
在此示例中,我們的ADD鍵恰好是FOREIGN KEY. 雖然鍵始終引用列,但鍵本身必須有自己的名稱,以區(qū)分列的數據和鍵的概念邏輯。我們命名我們的鍵foreign_key_name并指定該鍵將作用于哪一列(column_name)。因為這是一個外鍵,所以我們需要指定我們希望它與哪個表的主鍵關聯(lián)。REFERENCES parent_table(primary_key_column)表示該表中的外鍵對應于名為 的表中名為primary_key_column的列中保存的值parent_table。
語句ON DELETE和ON UPDATE是分別在父表的主鍵被刪除或更新時發(fā)生的操作。ON DELETE CASCADE如果相應的主鍵消失,將導致我們的表外鍵被刪除。
添加列
添加列遵循我們創(chuàng)建表時使用的相同語法。一個有趣的附加功能是能夠將新列放置在現有列之前或之后:
ALTER TABLE table_name ADD COLUMN column_name [DATA_TYPE] [FIRST|AFTER existing_column];
當引用PostgreSQL數據庫中的表時,我們必須指定所屬的模式。因此,ALTER TABLE table_name變?yōu)锳LTER TABLE schema_name.table_name. 這適用于我們引用表的任何時候,包括創(chuàng)建和刪除表時。
突擊測驗
下面的語句使用了我們迄今為止所學到的有關修改和創(chuàng)建表結構的所有元素。你能看出這里發(fā)生了什么嗎?
CREATE TABLE vendors( vdr_id int not null auto_increment primary key, vdr_name varchar(255) )ENGINE=InnoDB; ALTER TABLE products ADD COLUMN vdr_id int not null AFTER cat_id; ALTER TABLE products ADD FOREIGN KEY fk_vendor(vdr_id) REFERENCES vendors(vdr_id) ON DELETE NO ACTION ON UPDATE CASCADE;
丟棄數據
危險區(qū)域:這是我們可能開始把事情搞砸的地方。刪除列或表會導致數據完全丟失:每當您看到“刪除”一詞時,都會感到害怕。
如果您確定知道自己在做什么并且想要刪除表列,可以按如下方式完成:
ALTER TABLE tableDROP column;
刪除表會破壞表結構及其中的所有數據:
DROP TABLE table_name;
另一方面,截斷表將清除表中的數據,但保留表本身:
TRUNCATE TABLE table_name;
刪除外鍵
像表和列一樣,我們也可以刪除鍵:
ALTER TABLE table_name DROP FOREIGN KEY constraint_name;
這也可以通過刪除 CONSTRAINT 來處理:
ALTER TABLE public.jira_epiccolors DROP CONSTRAINT jira_epiccolors_pkey;
使用視圖(特定于 PostgreSQL)
最后,讓我們探討一下創(chuàng)建視圖的行為。PostgreSQL 可以處理三種類型的視圖:
簡單視圖:代表基礎表數據的虛擬表。簡單視圖是自動可更新的:系統(tǒng)將允許在視圖上使用 INSERT、UPDATE 和 DELETE 語句,就像在常規(guī)表上一樣。
物化視圖:PostgreSQL 將視圖概念擴展到了一個新的水平,允許視圖“物理”存儲數據,我們將這些視圖稱為物化視圖。物化視圖緩存復雜查詢的結果,然后允許您定期刷新結果。
遞歸視圖:如果不深入研究遞歸報告的復雜(但很酷?。┕δ埽f歸視圖有點難以解釋。我不會詳細介紹,但這些視圖能夠表示多層深入的關系。如果您好奇的話,可以快速體驗一下:
示例RECURSIVE 查詢:
WITH RECURSIVE reporting_line AS ( SELECT employee_id, full_name AS subordinates FROM employees WHERE manager_id IS NULL UNION ALL SELECT e.employee_id, ( rl.subordinates || ' > ' || e.full_name ) AS subordinates FROM employees e INNER JOIN reporting_line rl ON e.manager_id = rl.employee_id ) SELECT employee_id, subordinates FROM reporting_line ORDER BY employee_id;
輸出:
employee_id | subordinates -------------+-------------------------------------------------------------- 1 | Michael North 2 | Michael North > Megan Berry 3 | Michael North > Sarah Berry 4 | Michael North > Zoe Black 5 | Michael North > Tim James 6 | Michael North > Megan Berry > Bella Tucker 7 | Michael North > Megan Berry > Ryan Metcalfe 8 | Michael North > Megan Berry > Max Mills 9 | Michael North > Megan Berry > Benjamin Glover 10 | Michael North > Sarah Berry > Carolyn Henderson 11 | Michael North > Sarah Berry > Nicola Kelly 12 | Michael North > Sarah Berry > Alexandra Climo 13 | Michael North > Sarah Berry > Dominic King 14 | Michael North > Zoe Black > Leonard Gray 15 | Michael North > Zoe Black > Eric Rampling 16 | Michael North > Megan Berry > Ryan Metcalfe > Piers Paige 17 | Michael North > Megan Berry > Ryan Metcalfe > Ryan Henderson 18 | Michael North > Megan Berry > Max Mills > Frank Tucker 19 | Michael North > Megan Berry > Max Mills > Nathan Ferguson 20 | Michael North > Megan Berry > Max Mills > Kevin Rampling (20 rows)
創(chuàng)建視圖
創(chuàng)建簡單視圖就像編寫標準查詢一樣簡單!所需要做的就是在查詢之前添加CREATE VIEW view_name AS,這將為我們創(chuàng)建一個保存的位置,以便我們始終返回并引用此查詢的結果:
CREATE VIEW comedies AS SELECT * FROM films WHERE kind = 'Comedy';
走出去并開始 SQLing
我強烈鼓勵任何人養(yǎng)成手動編寫 SQL 查詢的習慣。有了正確的 GUI,自動完成功能就可以成為您最好的朋友。
明確地強迫自己編寫查詢而不是復制和粘貼任何內容迫使我們認識到,例如 SQL 的操作順序。事實上,這個查詢擁有正確的語法......
SELECT *FROM table_nameWHERE column_name = 'Value';
...而這個則沒有:文章來源:http://www.zghlxwxcb.cn/article/574.html
SELECT *WHERE column_name = 'Value'FROM table_name;
掌握 SQL 的微妙之處是速度極快和幾乎一無所知之間的區(qū)別。好消息是,您會開始發(fā)現這些概念并不像它們曾經看起來那樣令人畏懼,因此從“糟糕的數據工程師”到“專家”的道路是一個輕松的勝利,如果不這樣做那就太愚蠢了拿。文章來源地址http://www.zghlxwxcb.cn/article/574.html
到此這篇關于從零開始學習SQL操作:修改數據庫和表的文章就介紹到這了,更多相關內容可以在右上角搜索或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!