日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MYSQL四

發(fā)布時間:2024/7/19 数据库 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MYSQL四 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
-- ########## 01、ER關(guān)系 ##########-- ER關(guān)系(邏輯描述) -- A:E---Entity簡寫,實體,具有相同屬性(特征)的對象歸為同一實體 -- Attribute屬性,描述實體具有的特征,一個實體可以有若干個屬性來描述 -- B:R---Relationship簡寫,關(guān)系/聯(lián)系,數(shù)據(jù)對象彼此之間的互相關(guān)聯(lián)的關(guān)系-- ER關(guān)系常見的三種形式: -- 1、一對一關(guān)系(1:1):例如:夫妻關(guān)系、一個國家只有一個最高領(lǐng)導(dǎo)人、向日葵... -- 2、一對多關(guān)系(1:n):例如:一把鎖有多把鑰匙、一個房子有多個門、一個皇帝有多個太監(jiān)、一個部門有多個員工... -- 3、多對多關(guān)系(m:n):例如:參加招聘會的企業(yè)和同學(xué)、學(xué)生選課、飯桌上的菜和吃菜的人...-- ########## 02、數(shù)據(jù)庫設(shè)計 ########## -- 設(shè)計的過程不是一步到位的,也不可能一步到位,都是一個反復(fù)迭代的過程-- 需求:商城里會員顧客購買若干數(shù)量的商品 -- 提供的數(shù)據(jù)如下: -- 顧客編號為1的顧客張三購買了3個商品編號為123的A商品 -- 顧客編號為2的顧客李四購買了4個商品編號為456的B商品 -- 顧客編號為1的顧客張三購買了3個商品編號為123的A商品(數(shù)據(jù)來自不同渠道) -- 顧客編號為3的顧客王五購買了5個商品編號為123的A商品 -- 顧客編號為1的顧客張三購買了2個商品編號為456的B商品 -- .....-- 分析:這可能就是業(yè)務(wù)提供方描述的一個場景,數(shù)據(jù)庫設(shè)計時,會從中挖掘出很多信息 -- 數(shù)據(jù)整理:去除無效的數(shù)據(jù),比如:去除重復(fù)的數(shù)據(jù)(可能來自不同的渠道,但是其實描述的是相同的數(shù)據(jù)內(nèi)容)-- 廣大開發(fā)人員在長期的數(shù)據(jù)庫設(shè)計過程中歸納整理了幾個稱為【范式】的東西 -- 【第1范式(1NF)】為了保證表中的行的數(shù)據(jù)是唯一的,屬性是原子的。 -- 也就是說,行的唯一性通過在表中定義一個唯一的主鍵來實現(xiàn) -- 注意:這里說的唯一的主鍵,沒有說主鍵只能建立在一個字段上CREATE TABLE order_1nf (orderid INT,productid INT,quantity INT,customerid INT,customername VARCHAR(10) NOT NULL,productname VARCHAR(20) NOT NULL,PRIMARY KEY(orderid, productid) ); DESC order_1nf;-- 【第2范式(2NF)】首先數(shù)據(jù)必須滿足第1范式,其次要求非鍵屬性(Nonkey Attribute)和候選鍵之間必須滿足一定的條件。 -- 也就是說,一個非鍵屬性不能只完全函數(shù)依賴于候選鍵的一部分。 -- 分析:order_1nf表中,customerid這個非鍵屬性只依賴于主鍵(候選鍵)(orderid, productid)的一部分orderid,所以,需要把order_1nf表進行分解 CREATE TABLE order_2nf (orderid INT,customerid INT,customername VARCHAR(10) NOT NULL,PRIMARY KEY(orderid) ); CREATE TABLE orderdetail_2nf (orderid INT,productid INT,quantity INT,PRIMARY KEY(orderid) ); CREATE TABLE product_2nf (productid INT,productname VARCHAR(20) NOT NULL,PRIMARY KEY(productid) );-- 【第3范式(3NF)】首先數(shù)據(jù)必須滿足第2范式,其次要求所有的非鍵屬性必須非傳遞依賴于候選鍵。 -- 也就是說,一個非鍵屬性不能依賴于其他的非鍵屬性。 -- 分析:order_2nf表中,customername依賴于customerid這個非鍵屬性,所以,需要把order_2nf表進行分解 CREATE TABLE order_3nf (orderid INT,customerid INT,PRIMARY KEY(orderid) ); CREATE TABLE customer_3nf (customerid INT,customername VARCHAR(10) NOT NULL,PRIMARY KEY(customerid) ); CREATE TABLE orderdetail_3nf (orderid INT,productid INT,quantity INT,PRIMARY KEY(orderid) ); CREATE TABLE product_3nf (productid INT,productname VARCHAR(20) NOT NULL,PRIMARY KEY(productid) );-- 注意:實際開發(fā)中,一般必須達到第2范式及以上,不過有時處于操作數(shù)據(jù)效率的考慮,設(shè)計時也會使用第2范式的設(shè)計(即包含了一些冗余)-- 需求:設(shè)計 學(xué)生選課的數(shù)據(jù)庫設(shè)計 -- 學(xué)生可以選擇多門課程,一門課程可以有多個學(xué)生,一個老師可以帶多門課程,一門課程只能由一個老師來帶,每個學(xué)生選的課程有一個相應(yīng)的課程成績 -- 分析: -- 實體:學(xué)生、課程、老師、成績(這四個名詞拿出來作為候選實體) -- 實體間的關(guān)系:"一個老師可以帶多門課程,一門課程只能由一個老師來帶"這句話描述了課程 和 老師 之間的關(guān)系是多對一的關(guān)系 -- "學(xué)生可以選擇多門課程,一門課程可以有多個學(xué)生"這句話描述了 學(xué)生 和 課程之間的關(guān)系是多對多的關(guān)系 -- "每個學(xué)生選的課程有一個相應(yīng)的課程成績"這句話讀起來 成績 像是 課程的一個屬性,并且是一個學(xué)生的一門課程的一個成績, -- 結(jié)合上述應(yīng)該要先解決多對多的關(guān)系,再看這個成績怎么設(shè)計-- 首先設(shè)計較為獨立的實體 -- 老師信息實體 CREATE TABLE teacherinfo (-- 老師編號teacherid INT AUTO_INCREMENT PRIMARY KEY,-- 老師姓名teachername VARCHAR(10) NOT NULL,-- 老師性別teachergender ENUM('男', '女') NOT NULL,-- 老師年齡teacherage INT NOT NULL ); -- 學(xué)生信息實體 CREATE TABLE studentinfo (-- 學(xué)生編號studentid INT AUTO_INCREMENT PRIMARY KEY,-- 學(xué)生姓名studentname VARCHAR(10) NOT NULL,-- 學(xué)生性別studentgender ENUM('男', '女') NOT NULL,-- 學(xué)生年齡studentage INT NOT NULL );-- 接著設(shè)計一對多的關(guān)系,可以在作為多的實體中添加作為一的實體的主鍵作為非鍵屬性的值 -- 也可以在作為一的實體中添加作為多的實體的主鍵作為非鍵屬性的值 -- 顯然,前者操作起來比較簡單,也是一對多關(guān)系的經(jīng)典設(shè)計方式-- 課程信息實體 CREATE TABLE courseinfo (-- 課程編號courseid INT AUTO_INCREMENT PRIMARY KEY,-- 課程名稱coursename VARCHAR(10) NOT NULL,-- 老師編號teacherid INT NOT NULL );-- 最后考慮多對多的關(guān)系,首先考慮套用一下一對多的關(guān)系的設(shè)計,在courseinfo表中放入studentinfo表的主鍵,在studentinfo表中放入courseinfo表的主鍵 -- 這樣的設(shè)計有一個問題,作為學(xué)生信息,并不確定有多少課程被選,即無法確定多個課程主鍵的數(shù)量,當(dāng)然寫在一個字段中也可以,但是操作又很麻煩 -- 同樣,作為課程信息,也不確定有多少學(xué)生選擇 -- 既然考慮這兩個實體中都要放入對方的主鍵作為屬性使用,這里不妨制作一個獨立的關(guān)系實體,包含有著兩個實體的主鍵作為屬性,即可輕松實現(xiàn)多對多的關(guān)系 -- 而且,這個獨立的關(guān)系實體還可以包含有和多對多關(guān)系相關(guān)的其他屬性,比如:成績-- 成績信息實體(學(xué)生 和 課程 多對多 關(guān)聯(lián)關(guān)系表) CREATE TABLE scoreinfo (-- 成績編號scoreid INT AUTO_INCREMENT PRIMARY KEY,-- 學(xué)生編號studentid INT NOT NULL,-- 課程編號courseid INT NOT NULL,-- 成績分?jǐn)?shù)score DECIMAL(4, 1) NOT NULL );-- ########## 03、匯總數(shù)據(jù)(進階) ##########-- 模擬數(shù)據(jù) INSERT INTO scoreinfo VALUES(NULL, 1, 1, 60), (NULL, 1, 2, 90), (NULL, 1, 3, 80), (NULL, 1, 4, 70), (NULL, 1, 5, 40), (NULL, 2, 1, 70), (NULL, 2, 2, 50), (NULL, 2, 3, 70), (NULL, 2, 4, 30), (NULL, 2, 5, 90), (NULL, 3, 1, 55), (NULL, 3, 2, 65), (NULL, 3, 3, 75), (NULL, 4, 1, 87), (NULL, 4, 2, 63), (NULL, 4, 4, 28);SELECT * FROM scoreinfo;-- 需求:獲取每個同學(xué)的成績總分和成績平均分 -- 思路:因為每個同學(xué)可能有多門課程的成績,所以這里需要基于學(xué)生編號進行分組,并使用聚合函數(shù) SELECT studentid AS 學(xué)生編號, SUM(score) AS 成績總分, AVG(score) AS 成績平均分 FROM scoreinfo GROUP BY studentid;-- 需求:列出每門功課的最高分、最低分,該門功課的總分、該門功課的平均分 -- 思路:因為每門功課可能對應(yīng)多個學(xué)生的成績,所以這里需要基于課程編號進行分組,并使用聚合函數(shù) SELECT courseid AS 課程編號, MAX(score) AS 最高分, MIN(score) AS 最低分, SUM(score) AS 總分, AVG(score) AS 平均分 FROM scoreinfo GROUP BY courseid;-- 需求:列出平均分高于65分的同學(xué)的學(xué)生編號及其平均分 -- 思路:首先想到的是使用分組子句(GROUP BY) 和 篩選條件子句(WHERE)-- 1、語義錯誤:先對scoreinfo這個集合進行了條件篩選,把65分以上的成績都留下來了,再按學(xué)生編號進行分組 SELECT studentid AS 學(xué)生編號, AVG(score) AS 平均分 FROM scoreinfo WHERE score > 65 GROUP BY studentid;-- 2、語法錯誤:參照順序圖,因為WHERE子句先于GROUP BY子句執(zhí)行,所以在WHERE子句中無法提前使用聚合函數(shù) -- 錯誤代碼: 1111 Invalid use of group function SELECT studentid AS 學(xué)生編號, AVG(score) AS 平均分 FROM scoreinfo WHERE AVG(score) > 65 GROUP BY studentid;-- 正確寫法:引入 HAVING 子句,對于分組后的數(shù)據(jù)進行條件篩選 SELECT studentid AS 學(xué)生編號, AVG(score) AS 平均分 FROM scoreinfo GROUP BY studentid HAVING AVG(score) > 65;-- 注意: -- 1、WHERE子句關(guān)注的是行的記錄的條件篩選 -- 2、HAVING子句關(guān)注的是組的記錄的條件篩選SELECT * FROM scoreinfo HAVING score > 70; -- 上句可以理解為: SELECT * FROM scoreinfo GROUP BY scoreid HAVING score > 70; -- 下面兩句可以理解為:因為按照scoreid這個主鍵進行分組,每組就是一條記錄,對這一條記錄使用聚合函數(shù)還是它自身 SELECT * FROM scoreinfo GROUP BY scoreid HAVING AVG(score) > 70; SELECT * FROM scoreinfo GROUP BY scoreid HAVING SUM(score) > 70; -- 也就等價于 SELECT * FROM scoreinfo WHERE score > 70;-- 需求:列出單科課程(課程編號)對應(yīng)的所有同學(xué)(多行顯示同學(xué)編號) -- 如下寫法不正確,因為這樣分組后select獲取的是每一組的第一條記錄 -- 思考:為什么到處使用分組? SELECT courseid AS 課程編號, studentid AS 學(xué)生編號 FROM scoreinfo GROUP BY courseid;-- 正確寫法 SELECT courseid AS 課程編號, studentid AS 學(xué)生編號 FROM scoreinfo ORDER BY courseid; -- 或者 SELECT courseid AS 課程編號, studentid AS 學(xué)生編號 FROM scoreinfo ORDER BY courseid, studentid;-- 需求:列出單科課程(課程編號)對應(yīng)的所有同學(xué)(單行顯示同學(xué)編號,多個編號之間以逗號連接) -- 思路:首先考慮分組,分組后select時使用字符函數(shù)CONCAT,但是這樣拼接的是每一組的第一條記錄中studentid SELECT courseid AS 課程編號, CONCAT(studentid, ',') AS 學(xué)生編號 FROM scoreinfo GROUP BY courseid;-- 到MySQL手冊中找靈感,查找了一下和GROUP BY子句相關(guān)的內(nèi)容,看到GROUP_CONCAT(expr) :該函數(shù)返回帶有來自一個組的連接的非NULL值的字符串結(jié)果。 SELECT courseid AS 課程編號, GROUP_CONCAT(studentid) AS 學(xué)生編號 FROM scoreinfo GROUP BY courseid;-- 需求:列出單科課程(課程編號)對應(yīng)的學(xué)生人數(shù) SELECT courseid AS 課程編號, COUNT(studentid) AS 選擇該門課程的學(xué)生人數(shù) FROM scoreinfo GROUP BY courseid;-- 需求:列出單科課程(課程編號)對應(yīng)的學(xué)生人數(shù),并進行總計 -- 思路:總計操作使用 WITH ROLLUP 子句 SELECT courseid AS 課程編號, COUNT(studentid) AS 選擇該門課程的學(xué)生人數(shù) FROM scoreinfo GROUP BY courseid WITH ROLLUP;-- 需求:列出單科課程(課程編號)對應(yīng)的所有學(xué)生(單行顯示學(xué)生編號),并進行總?cè)藬?shù)的統(tǒng)計(單行顯示學(xué)生編號) SELECT courseid AS 課程編號, GROUP_CONCAT(studentid) AS 選擇該門課程的學(xué)生編號 FROM scoreinfo GROUP BY courseid WITH ROLLUP;

?

轉(zhuǎn)載于:https://www.cnblogs.com/java-le/p/6443404.html

總結(jié)

以上是生活随笔為你收集整理的MYSQL四的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。