程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL入門

編輯:MySQL綜合教程

MySQL入門


 

本章主要介紹MySQL關系數據庫管理系統(Relational Database Management System,RDBMS)和MySQL所使用的結構化查詢語言(Structured Query Language,SQL)。其中,列出了應該掌握的基本術語和概念,描述了示例所要用到的樣本數據庫sampdb,並且提供了一個用於展示如何使用`MySQL創建數據庫並與之進行交互操作的教程。
如果你對數據庫系統還不甚了解,或者還不是很肯定自己是否需要學習它,甚至還不肯定是否需要使用它,那麼請從本章開始。如果你對MySQL和SQL還一無所知,並且需要一個入門指南,那麼也請從本章開始。對MySQL或其他數據庫系統已有一定經驗的讀者,則可以略讀一下本章的內容。不過,為了你能對全書所用那個數據庫sampdb的目的和內容更熟悉,希望可以閱讀一下1.2節。

1.1 MySQL的用途

本節描述的是MySQL數據庫系統的用途,具體描述了“MySQL可以干什麼”,以及“它如何才能給你提供幫助”。如果你已經明白數據庫的用途(也許你正在思考某個問題,到這裡來只是想要找出“如何使用MySQL來解決它”的答案),那麼可以直接翻閱到1.2節。
數據庫系統在本質上是一種高效的管理大量列表信息的辦法。這些信息的來源可能多種多樣。它可能是研究數據、業務記錄、客戶需求、體育統計、銷售報告、個人信息、人事檔案、bug報告或者學生成績。發揮數據庫系統強大作用的時機在於:想要組織和管理的信息非常龐大或復雜,以至於所有記錄采用手工處理會變得異常繁重。對於每天處理上百萬條事務的大公司來說,數據庫是必不可少的。不過,即使只有一個人的小公司,也可能會維護很多的信息,甚至多到需要用一個數據庫來管理它。假設有下面這些情況。
你在牙科診所工作,在那裡需要管理好患者的跟蹤記錄:何人何時到訪、做了些什麼、下次預約信息、保險信息等。 你收集了多年的研究數據,為了發表而需要對它們進行分析。你要從大量原始數據裡提煉出摘要性的信息,並取出選中的觀察子集進行詳細的統計分析。 你是一名教師,需要跟蹤學生的成績和考勤。每次考試結束,你都需要記錄每一個學生的分數。雖然將成績記錄到成績冊上很簡單,但之後的成績分析卻很繁瑣。你很想避免為了確定分數曲線,而對每次考試的分數進行排序;也真的很不願意在期末時為了確定最終成績,而把每個學生的成績都加起來。統計每個學生的考勤也很無趣。 你在某個組織機構(可能是一個專業團體、一個俱樂部、一個交響樂團或者一個健身俱樂部)擔任秘書一職,具體負責維護機構成員名錄的工作。你每年都要為所有成員生成一份打印名錄,名錄是用文字處理軟件管理的,每當成員資料有變化時你都得編輯更新。你非常厭倦這種維護名錄的方式,因為它限制了你的發揮,主要表現在:很難對名錄條目按不同方式進行排序;無法輕松地選到每一條目的指定部分,如列出人名和電話號碼;更不能輕松地找出一組的成員,如需要盡快更新成員資格的成員。如果有辦法,就可以省卻每月通過翻閱這些條目來找出那些需要更新成員資格的成員的工作。你聽說過“無紙化辦公”,知道它是電子化記錄發展的結果,但你還未見過它所帶來的任何好處。雖然成員資格記錄是電子化的,但具有諷刺意味的是,它們記錄的形式除了能將名錄打印成紙質的以外,很難用作他途! “機構秘書”場景。該機構有一些特點:其成員對美國歷史很感興趣(因沒有一個更好的名字,所以姑且稱其為“美史聯盟”)。所有成員都要定期繳納一定的費用以維持其成員資格。繳納的費用會用於一些正常開支,如出版通訊——《Chronicles of U.S. Past 》(美國編年史)。該聯盟運營著一個小型網站,但還未被充分開發出來,而你很想要扭轉這一局面。 “成績考評”場景。你是一名教師,要負責考評期間的各種考試與測驗,記錄分數和打分。之後,你要確定出最終成績,並把它們隨同考勤情況一同上交到學校辦公室。 你必須決定數據庫裡的哪些內容是你所想要的——即那些你要實現的目標。 你必須決定需要將哪些內容放入數據庫——即你想要跟蹤的數據是什麼。 你想要以不同格式輸出名錄,同時按照不同的應用程序來定制信息。有一個目標是每年生成打印好的名錄——這是聯盟一直以來的一個需求,要繼續實施下去。你可能還會想到名錄信息的其他用途,例如向出席聯盟年會的人員提供一份打印好的最新成員名單。這兩個應用程序涉及的信息是不同的。打印名錄程序需要用到每個成員條目的所有內容。而年會程序則只需要提取出成員的姓名即可(使用文字處理軟件無法輕松完成這項工作)。 你想要在名錄裡搜索出滿足不同條件成員。例如,你想要知道近期有哪些成員需要更新成員資格。你還需要另一個搜索相關的應用程序,用來維護每個成員各自的關鍵字列表。這些關鍵字描述了所有成員都特別感興趣的一些美國歷史時期,如南北戰爭(Civil War)、經濟大蕭條(Depression)、民權法案(civil right)、托馬斯·傑斐遜(Thomas Jefferson)總統的生平事跡。有時,有些成員會要求你為他們提供一份與其志趣相投的其他成員名單,而你也很願意滿足這些需求。 你想要將名錄發布到聯盟網站上去。這樣做能讓你和所有成員都受益。如果你能通過某些自動化的過程將名錄轉換為Web頁面,那麼名錄的在線版本將總能保持最新,而這是紙質形式無法做到的。如果在線名錄能支持搜索功能,那麼成員們便能輕松地自行查找信息。例如,如果某成員想要知道其他還有誰對“南北戰爭”感興趣,那麼他便可以自行查找,完全用不著等你幫他搜索,而你也不用抽時間去處理這件事情。 如果數據庫中的信息能夠以在線名錄的形式放到網站上去,那麼你也可以讓這些信息以其他方式流轉。例如,讓成員能夠在線修改他們自己的資料,並更新到數據庫。這樣,你就不用自己負責所有的編輯工作,而且這也能讓名錄裡的信息更加准確。 如果你把電子郵件地址也存儲到數據庫裡,那麼你就可以利用它們來給成員發送電子郵件,提醒他們及時更新自己的資料。郵件內容可以顯示出成員的當前資料,請成員們進行檢查,並提示他們如何使用網站提供的功能完成必要的修改。 數據庫還可以在很多方面拓展聯盟網站的用途,而並不僅限於成員資格列表。聯盟通訊《Chronicles of U.S. Past》有一個兒童專欄,其中每一期都會包含一個歷史知識測驗。最近幾期的重點是美國總統的傳記。聯盟網站上也可以設置一個兒童專區,把那些測驗題目放在上面。或許這個專區還可以弄成互動的,比如將做過的測驗信息放入數據庫,讓Web服務器在數據庫裡查詢問題的答案,然後呈現給訪客。 是不是想太多了?實現起來工作量會很大吧? MySQL能實現所有這些目標嗎? 最後,還有一個很重要的問題:總計要花費多少錢?畢竟聯盟的預算是有限的。 對於每一次測驗或考試,你都要記錄分數。如果是考試,你還需要對分數進行排序,以便查看它們並確定每一個字母成績(包括A、B、C、D和F)所代表的界線。 在期末,你需要把計算出每一個學生的總分數,對這些總分數進行排序,並以此為基礎確定出成績。總分數可能需要加權計算,因為你可能需要讓考試比測驗的權重更大。 在期末,你還要向學校辦公室提供學生的考勤情況。

數據庫(DataBase,即RDBMS裡的DB)是一個用來存儲信息的倉庫,它的結構簡單、規則。

數據庫裡的數據集都被組織成表(table)。

每個表由多個行(row)和列(column)組成。

表中的每一行稱為一條記錄(record)。

記錄可以包含多項信息;表裡的每一列對應於其中的一項。

管理系統(Management System,即RDBMS裡的MS)是一個軟件,我們可以通過它來插入(insert)、檢索(retrieve)、修改(modify)或刪除(delete)記錄。

關系(Relational,即RDBMS裡的R)一詞表示這是一種特殊的DBMS,其長處在於通過查找兩個表裡的共同元素,將分別存放於兩個表裡的信息聯系(即匹配)起來。RDBMS的強大之處在於:它能方便地將這些表裡的數據提取出來,並把相關表裡的信息結合起來生成答案,回答那些只靠單個表無法回答的問題。(事實上,“關系”的正式定義與我在本書中用它的方式有所不同。為此,我先向那些純粹主義者道歉。不過,我的定義更有助於表達出RDBMS的用途。) 服務器強制執行並發控制,可以防止兩個用戶同時修改同一條記錄。所有客戶端請求都要經過服務器,因此服務器會負責安排處理它們的先後順序。即使出現多個客戶端同時訪問同一個表的情況,它們也不用先找到對方進行協商。它們只需把自己的請求發往服務器,然後由服務器來決定執行這些請求的順序。 不是只有在數據庫所在的那台機器上才能登錄。MySQL工作在網絡環境裡,因此你可以在任意地方運行MySQL客戶端程序,它都能夠通過網絡連接到服務器。距離不是問題!你可以在世界的任何地方訪問服務器。例如,你的服務器位於澳大利亞,那麼就算你帶著筆記本電腦旅行到了冰島,你也仍然可以訪問自己的數據庫。這是否意味著任何人都能夠通過互聯網看到你的數據呢?答案是“不能”。MySQL有一套靈活的安全機制,你可以設定只有得到授權的人才能訪問。此外,你還可以進一步限制這些人的操作。例如,財務部的Sally應該有查看和更新(修改)記錄的權限;而服務台的Phil卻只應該有查看記錄的權限。總之,你可以把這種訪問權限控制細化到每一個人。如果你只想運行一個自屬的系統,那麼你完全可以把訪問權限設置為只允許服務器上的客戶端程序進行連接。 了解MySQL所能理解的SQL基礎知識。(MySQL與其他RDBMS所使用的SQL有所不同,因此你最好也能快速浏覽一下本節的內容,從而確認一下MySQL的SQL實現與你熟悉的版本是否存在差異。) 了解MySQL自帶的標准客戶端程序是如何與MySQL服務器進行通信的。前一節講過,MySQL采用的是“客戶端/服務器”體系結構。其中,服務器運行在數據庫所在的機器上;而客戶端則是通過網絡連接到服務器。本教程主要依賴於客戶端程序mysql,它首先讀取你輸入的SQL查詢語句,把它們發送到服務器執行,然後把執行結果顯示在你面前。客戶端mysql可以在MySQL所支持的所有平台上運行,並且提供了與服務器進行交互的最直接的方式。不過根據需要,有些示例會使用mysqlimport或者mysqlshow來代替。 必須安裝MySQL軟件。 要有一個能夠連接數據庫服務器的MySQL賬號。 要有一個用來操作的數據庫。 -h host_name(另一種形式是:--host=host_name) -u user_name(另一種形式是:--user=user_name) -p(另一種形式是:--password) president表。其中包含美國歷任總統的描述性記錄。我們需要用它來實現聯盟網站上的在線小測驗(對聯盟通訊兒童專欄裡出現的小測驗進行交互式模擬)。 member表。用於保存聯盟每位成員的最新個人資料。我們可以用它來創建成員名錄的印刷版本和在線版本,用它來向到期成員自動發送提醒通知,還可以用它做很多其他事情。 姓名。在表裡,表示姓名的方式有好幾種,如使用單列包含整個名字,或用不同的列分別表示姓(last name)和名(first name)。使用單列來表示當然更簡單一些,但這種做法不夠靈活,存在一些限制。 出生地(城市和州)。與姓名的情況類似,它既可以用一列來表示,也可以用多列表示。采用單列來表示的做法顯得更簡單些;但與姓名的情況一樣,使用多列能實現某些更復雜的操作。例如,若把州名與市名分開表示,那麼像“找出出生在某個州的總統共有多少位”這種類似的操作便能輕易地實現。我們將使用兩個單獨的列來分別存放州名與市名。 出生日期和逝世日期。這裡唯一需要特殊處理的事情是:因為有些總統依然健在,所以我們不能要求必須填上逝世日期。特殊值NULL的意思即表示“無值”,因此我們可以在逝世日期列裡用它來表示該位總統“依然健在”。 姓名。我們將沿用與president表相同的3列表示法:姓、名和姓名後綴。 ID編號。這是一個唯一值,為每個首次加入的成員分配一個。聯盟此前從未對成員編過號,但現在需要所有的記錄都更系統化,因此這裡需要這個值。(希望你能不斷發現MySQL的好處,並找到更多將編號應用於聯盟記錄的方式。當想要將member表裡的行,與你所創建的成員相關的其他表建立關聯時,使用編號則會比使用姓名更容易實現。) 有效期。所有成員必須定期更新其成員資格,以避免過期。對於某些應用程序,可能還需要把最近一次資格更新後的起始日期存儲起來,但“美史聯盟”不需要這樣做。成員資格的有效期是一個變值(通常有1年、2年、3年或者5年之分),而最近一次的資格更新日期也並不能說明該成員下一次的資格更新日期一定是在什麼時候。因此,我們需要把成員資格的截止日期存儲起來。此外,聯盟還提供了終身成員資格。雖然我們可以用一個很遙遠的日期來表示這種情況,但使用NULL會更合適,因為“無值”在邏輯上正好對應於“永不失效”。 電子郵件地址。公開電子郵件地址可以使興趣相投的成員交流起來更方便。作為聯盟的秘書,在有了這些地址之後,就可以用電子郵件來向成員發送成員資格更新通知,而不用郵寄信件了。與到郵局寄信相比,這種做法既方便又省錢。你還可以利用電子郵件把每位成員的個人最新資料發送給他們,讓他們在必要時更新信息。 通信地址。當與那些沒有電子郵件(或者長期沒有回復你郵件)的成員進行聯系時,你會需要這條信息。我們將使用多個列來分別存儲街道地址、城市名、州名和郵政編碼。 電話號碼。與地址列相似,主要用於聯系成員。 特殊興趣關鍵字。聯盟的每位成員對美國歷史肯定都很感興趣,但他們的興趣卻可能集中於某些特定的歷史時期。此列便是用於記錄這些興趣。每位成員都可以利用這些信息來尋找與自己興趣相投的其他成員。(嚴格來講,建立一個獨立的表可能會更好些,表中的每一行都由一個關鍵字和相關成員的ID組成。這點有些復雜,我們暫不作處理。) INT。它表示該列用於存放整數(無小數部分的數值)。 UNSIGNED。它表示該值不能為負數。 NOT NULL。它表示該列必須要填值,這可以防止創建的成員沒有ID號。 AUTO_INCREMENT。它是MySQL的一個特殊屬性,表示該列存放的是序號。AUTO_INCREMENT的工作原理為:當往member表裡添加新記錄時,如果沒有為member_id列提供值,那麼MySQL將自動生成下一個編號,並將它賦給該列。如果你顯式地將NULL賦給該列,結果也是一樣的。AUTO_INCREMENT的這種特性使得為每一位成員分配一個唯一的ID變得很簡單,因為MySQL會替我們生成這些值。 你需要把考試成績記錄在表格的每一個格裡,這些格都要按學生姓名和考試日期進行排列(姓名由上往下排列,考試日期則由左往右排列)。這正是我剛才講過的兩組信息當中的一組,而它正好對應於score表裡的內容。 你要如何才能知道各日期所對應的考試類型呢?你或許會這樣做:在日期上方寫一個T或Q。於是,你又在表格的頂部把考試日期與考試類型關聯起來了。這正是我剛才講過的兩組信息當中的第二組,而它也正好對應於grade_``event表裡的內容。 成績冊由行和列構成,電子表格也是如此。這使得它們在概念和外觀上都很相似。 電子表格程序能夠執行計算,因此可以使用計算字段來統計每個學生的分數。將測驗分數和考試分數按不同權重來統計可能會有點棘手,但相信你能辦到。 考試成績與考試事件和學生都有關聯:只有當與考試成績相關聯的學生ID和考試事件ID分別在student``表和grade_event表裡存在時,才允許考試成績進入score表。 類似地,考勤記錄與學生有關聯:只有與考勤相關聯的學生ID在student表裡存在時,才允許考勤情況進入absence表。 我們已將這兩列的組合設置成了一個PRIMARY KEY。這樣可以確保我們不會重復記錄某位學生在某次考試或測驗的分數。請注意,只有event_id和student_id的組合才具有唯一性。在score表裡,這兩個ID值自身都不具備唯一性。對於每一個event_id值(每位學生有一個)都會有多個分數行與之對應;對於每一個student_id值(每次考試或測驗有一個)也會有多行記錄相對應。 每一個ID列都需要用FOREIGN KEY子句來定義約束條件。此子句的REFERENCES部分表明這個ID列是與哪個表的哪一列相對應。event_id列的約束條件為:該列裡的每一個值都必須與grade_event表裡的某個event_id值相匹配。類似地,score表裡的每一個student_id值都必須與student表裡的某個student_id值相匹配。 score表依賴於grade_event表和student表,因此在創建score表之前必須先創建其依賴的表。類似地,adsence表依賴於student表,因此在創建adsence表之前,student表必須已存在。 在刪除表時,必須把上面的順序顛倒過來。如果不先刪除score表,就無法刪除grade_event表;如果不先刪除score表和absence表,也無法刪除student表。 按日期排序(我們已經操作過多次)。 搜索特定日期或日期范圍。 從日期值裡提取各組成部分,如年、月或日。 計算兩個日期之間的時間差。 通過將一個日期加上或減去一個時間間隔,計算出另一個日期。 不用事先知道被統計列裡有些什麼值。 只需一個查詢語句。 因為只用一個查詢便能獲得所有的結果,所以可以對輸出進行排序。 FROM子句指定了多個表名,因為需要從多個表裡檢索信息: ON子句指定了表grade_``event和score的連接條件,即這兩個表的event_id值必須相互匹配: FROM子句現在包含了student表,因為這條查詢語句除了要用到grade_``event表和score表以外,還需要用到它。 在前一個查詢裡,student_id列不會產生二義性,因此在引用它時,既可以不限定表名(student_id),也可以限定表名(score.student_id)。但在這個查詢裡,因為score表和student表都有student_id列,所以肯定會出現二義性。於是,為了避免產生二義性,必須將它們分別限定為score.student_id和student.student_id。 ON子句裡多了一個查詢條件,用於指定score表裡的行與student表裡的行必須基於學生ID匹配在一起: 這個查詢會顯示出學生的姓名,而不顯示學生的ID。(如果想要兩者都顯示,只需要在輸出列的列表裡加上student.student_id即可。) 它需要引用同一個表中的兩個實例,因此我們必須為它創建兩個別名(p1和p2),並用它們來將表中的同名列區別開來。由於列已有別名,所以在為表指定別名時, AS關鍵字就是可選項了。 每位總統的記錄都與其本身相匹配,但這並不是我們想要的輸出結果。在確保參與比較的總統名字都不相同的情況下, WHERE子句便能防止出現“行與其本身相匹配”的情況。 把連接參數存儲在一個選項文件裡。 利用shell的歷史命令功能輸入重復命令。 利用shell別名或腳本定義一個mysql命令行快捷方式。 利用mysql的輸入行編輯功能。 利用復制和粘貼。 利用批處理運行mysql程序。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved