1. 程式人生 > >MYSQL_2 多表 表關係 事務 一對多 多對多 sql練習

MYSQL_2 多表 表關係 事務 一對多 多對多 sql練習

 多表設計之外來鍵約束

     約束

     約束的作用

        約束是用來保證資料的完整性。

 單表約束

 主鍵約束

 唯一約束

 非空約束

 多表約束

 外來鍵約束:用來保證資料完整性(多表之間)。

演示外來鍵約束作用

建立一個部門表
create table dept(
	did int primary key auto_increment,
	dname varchar(20)
);
insert into dept values (null,'市場部');
insert into dept values (null,'人事部');
insert into dept values (null,'教研部');
建立一個員工表
create table employee(
	eid int primary key auto_increment,
	ename varchar(20),
	salary double,
	birthday date,
	sex varchar(10),
	dno int
);

insert into employee values (null,'張三',8000,'1988-09-01','男',3);

insert into employee values (null,'李四',9000,'1988-09-01','男',1);

insert into employee values (null,'王五',6000,'1988-09-01','男',2);

insert into employee values (null,'趙六',10000,'1988-09-01','男',3);

insert into employee values (null,'孫七',10000,'1988-09-01','男',1);

刪除其中的某個部門(是否可以)

    檢視資料


向員工表中插入一條記錄(沒有部門)
insert into employee values (null,'田八',10000,'1988-09-01','男',null);
刪除一個人事部
delete from dept where did = 2;

向剛才做的這兩個操作(插入一個沒有部門的員工,刪除一個帶有員工的部門)。這種情況都是不應該發生。這個時候需要在多表之間新增外來鍵約束。

新增外來鍵約束

在員工表上新增外來鍵

alter table employee add foreign key (dno) references dept(did);

設定外來鍵為非空
alter table employee modify dno int not null;

 表設計之表關係的介紹

 表與表之間的關係

    一對多的關係

         一對多的例子:

         一個部門下可以有多個員工,一個員工只能屬於某一個部門。

   多對多的關係

         多對多的例子:

         一個學生可以選擇多門課程,一門課程可以被多個學生選擇。

  一對一的關係

         一對一的例子:

         一個公司可以有一個註冊地址,一個註冊地址只能對一個公司。

表設計之一對多關係

一對多關係介紹

 一對多關係的建表原則

在多的一方建立外來鍵指向一的一方的主鍵


 多表設計之多對多

    多對多的關係介紹

       一個學生選擇多門課程,一門課程被多個學生所選擇

 多對多的建表的原則


需要建立中間表,中間表中至少兩個欄位,分別作為外來鍵指向多對多雙方的主鍵

 多表設計之一對一關係

 一對一關係的介紹

一個公司可以對應一個註冊地址,一個註冊地址只能對應一個公司

一對一關係建表原則


唯一外來鍵對應

假設是一對多,在多的一方建立外來鍵指向一的一方的主鍵,將外來鍵設定為unique

主鍵對應

將兩個表的主鍵建立對應關係即可。

 多表查詢之多表查詢的概述

 多表查詢的分類

 連線查詢

交叉連線:cross join

 交叉連線:查詢到的是兩個表的笛卡爾積。

 語法:

 select * from 1 cross join 2;

 select * from 1,2;

內連線:inner join(inner是可以省略的)

顯示內連線:在SQL中顯示的呼叫inner join關鍵字

語法:select * from 1 inner join 2 on 關聯條件;

隱式內連線:在SQL中沒有呼叫inner join關鍵字

語法:select * from 1,2 where 關聯條件;

外連線:outer join(outer可以省略的)

左外連線:

語法:select * from 1 left outer join 2 on 關聯條件;

右外連線

語法:select * from 1 right outer join 2 on 關聯條件;

 子查詢

 子查詢:一個查詢語句條件需要依賴另一個查詢語句的結果。

多表查詢之資料準備

資料準備(文字最後)

班級表資料的準備

學生表資料的準備

課程表資料的準備

學生選課表的準備

多表查詢之交叉連線

交叉連線

使用cross join關鍵字

select * from classes cross join student;
1.1.1.2不使用cross join關鍵字
SELECT * FROM classes,student;

多表查詢之內連線

內連線

顯示內連線

select * from classes c inner join student s on c.cid = s.cno;

隱式內連線
SELECT * FROM classes c,student s WHERE c.cid = s.cno;

多表查詢之外連線

外連線

左外連線

SELECT * FROM classes c LEFT OUTER JOIN student s ON c.cid = s.cno;

右外連線

select * from classes c right outer join student s on c.cid = s.cno;

多表查詢之內連線與外連線的區別

內連線和外連線的區別


多表查詢之子查詢

子查詢

in的子查詢

查詢學生生日在91年之後的班級的資訊。
select * from classes where cid in (SELECT cno FROM student WHERE birthday > '1991-01-01');

 帶exists的子查詢

l查詢學生生日大於91年1月1日,如果記錄存在,前面的SQL語句就會執行

select * from classes where exists (SELECT cno FROM student WHERE birthday > '1991-01-01');

帶any的子查詢
SELECT * FROM classes WHERE cid > ANY (SELECT cno FROM student )

帶all的子查詢
SELECT * FROM classes WHERE cid > ALL (SELECT cno FROM student)

多表查詢之練習

多表查詢的練習

查詢班級名稱,和班級總人數
SELECT c.cname,COUNT(*) FROM classes c,student s WHERE c.cid = s.cno GROUP BY c.cname;

查詢學生的姓名和學生所選的總課程平均成績。
select s.sname,avg(sc.score) from student s,stu_cour sc where s.sid = sc.sno group by s.sname;

查詢學生的姓名和學生的選課總數,顯示選課超過2門學生姓名。
select s.sname,count(*) from student s,stu_cour sc where s.sid = sc.sno group by s.sname having count(*) > 2;

查詢平均成績大於80分的學生的總數。
select count(*) from student s where s.sid in (SELECT sc.sno FROM stu_cour sc GROUP BY sc.sno HAVING AVG(sc.score) >  80);

查詢學生和平均成績,但是平均成績大於01班的任何一個學生的平均成績。
select s.sname,avg(sc.score) from student s,stu_cour sc where s.sid = sc.sno group by s.sname having avg(sc.score) > any(SELECT AVG(sc.score) FROM student s,stu_cour sc,classes c WHERE s.sid = sc.sno AND s.cno = c.cid AND c.cname= '01班' GROUP BY s.sname);

 事務的概述

     事務的概念

            事務:指的是邏輯上的一組操作,組成這組操作的各個邏輯單元,要麼全都成功,要麼全都失敗。

 MySQL中的事務管理

 環境準備

create table account(
	id int primary key auto_increment,
	name varchar(20),
	money double
);

insert into account values (null,'小張',10000);
insert into account values (null,'小鳳',10000);
轉賬案例
開啟事務:
start transaction;
提交事務
commit;
回滾事務
rollback;
提交事務

 回滾事務

 事務的特性:

 原子性

    原子性:事務的不可分割,組成事務的各個邏輯單元不可分割。

 一致性

    一致性:事務執行的前後,資料完整性保持一致。

 隔離性

    隔離性:事務執行不應該受到其他事務的干擾。

永續性

    永續性:事務一旦結束,資料就持久化到資料庫中。

 事務的隔離級別

 如果不考慮隔離性,引發一些安全問題

隔離性:一個事務的執行,不應該受到其他事務的干擾。

如果不考慮隔離性(一個事務執行受到其他的事務的干擾),引發一些安全問題,主要體現在讀取資料上:

 髒讀:一個事務讀到了另一個事務未提交的資料,導致查詢結果不一致

 不可重複讀:一個事務讀到了另一個事務已經提交的update的資料,導致多次查詢結果不一致。

 虛讀/幻讀:一個事務讀到了另一個事務已經提交的insert的資料,導致多次查詢結果不一致。

解決這些安全性問題:

設定事務的隔離級別:

 read uncommitted :髒讀,不可重複讀,虛讀都有可能發生

read committed :避免髒讀。但是不可重複讀和虛讀是有可能發生

repeatable read :避免髒讀和不可重複讀,但是虛讀有可能發生。

 serializable :避免髒讀,不可重複讀,虛讀。

事務的隔離級別的演示

演示髒讀

開啟兩個視窗A,B
設定A視窗的隔離級別為read uncommitted;
SET SESSION TRANSACTION ISOLATION LEVEL read uncommitted;

在A,B兩個視窗中開啟事務
start transaction;
在B視窗中完成轉賬的功能:
update account set money = money - 1000 where name= '小張';
update account set money = money + 1000 where name= '小鳳';
***** 事務未提交!!!

在A視窗中進行查詢
select * from account;

*****發現A視窗中已經查詢到轉賬成功了!!!已經發生了髒讀:一個事務中已經讀到了另一個事務未提交的資料。

事務的隔離級別演示

避免髒讀,演示不可重複讀發生

開啟兩個視窗A,B
設定A視窗的隔離級別為read committed;
SET SESSION TRANSACTION ISOLATION LEVEL read committed;

分別在兩個視窗中開啟事務:
start transaction;
在B視窗中完成轉賬
update account set money = money - 1000 where name= '小張';
update account set money = money + 1000 where name= '小鳳';

***** 沒有提交事務!!!

l 在A視窗中進行查詢:

select * from account;

***** 發現這個時候沒有轉賬成功!!!(沒有查詢到另一個事務未提交的資料:說明已經避免了髒讀)。
在B視窗中提交事務
commit;
在A視窗查詢
select * from account;

***** 發現這次的結果已經發生了變化!!!(已經發生不可重複讀:一個事務已經讀到了另一個事務提交的update的資料,導致多次查詢結果不一致。)

事務的隔離級別的演示

演示避免不可重複讀

分別開啟兩個視窗A,B
設定A視窗的隔離級別:repeatable read;
SET SESSION TRANSACTION ISOLATION LEVEL repeatable read;

在A,B兩個視窗中開啟事務:
start transaction;
在B視窗完成轉賬
update account set money = money - 1000 where name= '小張';
update account set money = money + 1000 where name= '小鳳';

***** 未提交事務!!!
在A視窗中進行查詢
select * from account;
***** 發現沒有轉賬成功:說明避免髒讀!!!
在B視窗中提交事務
commit;
在A視窗中再次查詢:

***** 發現在一個事務中的多次查詢結果是一致!!!(已經避免不可重複讀)。

事務的隔離級別演示

演示序列化

開啟兩個視窗A,B
設定A視窗的隔離級別:serializable
SET SESSION TRANSACTION ISOLATION LEVEL serializable;

分別在兩個視窗中開啟事務:
start transaction;

在B視窗中插入一條記錄
insert into account values (null,'小李',10000);

在A視窗中進行查詢
select * from account;
*****發現A視窗已經卡住了(說明事務不允許出現併發,A視窗需要等待B視窗事務執行完成以後,才會執行A視窗的事務。)當B視窗的事務結束(提交或者回滾),那麼A視窗馬上就會出現結果。
DROP TABLE IF EXISTS `classes`;/*!40101 SET @saved_cs_client     = @@character_set_client */;/*!40101 SET character_set_client = utf8 */;CREATE TABLE `classes` (  `cid` int(11) NOT NULL AUTO_INCREMENT,  `cname` varchar(20) DEFAULT NULL,  `cnum` int(11) DEFAULT NULL,  PRIMARY KEY (`cid`)) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;/*!40101 SET character_set_client = @saved_cs_client */;---- Dumping data for table `classes`--LOCK TABLES `classes` WRITE;/*!40000 ALTER TABLE `classes` DISABLE KEYS */;INSERT INTO `classes` VALUES (1,'01班',20),(2,'02班',30),(3,'03班',32),(4,'04班',41);/*!40000 ALTER TABLE `classes` ENABLE KEYS */;UNLOCK TABLES;---- Table structure for table `course`--DROP TABLE IF EXISTS `course`;/*!40101 SET @saved_cs_client     = @@character_set_client */;/*!40101 SET character_set_client = utf8 */;CREATE TABLE `course` (  `cid` int(11) NOT NULL AUTO_INCREMENT,  `cname` varchar(20) DEFAULT NULL,  PRIMARY KEY (`cid`)) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;/*!40101 SET character_set_client = @saved_cs_client */;---- Dumping data for table `course`--LOCK TABLES `course` WRITE;/*!40000 ALTER TABLE `course` DISABLE KEYS */;INSERT INTO `course` VALUES (1,'Java'),(2,'PHP'),(3,'C++');/*!40000 ALTER TABLE `course` ENABLE KEYS */;UNLOCK TABLES;---- Table structure for table `stu_cour`--DROP TABLE IF EXISTS `stu_cour`;/*!40101 SET @saved_cs_client     = @@character_set_client */;/*!40101 SET character_set_client = utf8 */;CREATE TABLE `stu_cour` (  `scid` int(11) NOT NULL AUTO_INCREMENT,  `sno` int(11) DEFAULT NULL,  `cno` int(11) DEFAULT NULL,  `score` int(11) DEFAULT NULL,  PRIMARY KEY (`scid`),  KEY `FK_stu_cour_001` (`sno`),  KEY `FK_stu_cour_002` (`cno`),  CONSTRAINT `FK_stu_cour_001` FOREIGN KEY (`sno`) REFERENCES `student` (`sid`),  CONSTRAINT `FK_stu_cour_002` FOREIGN KEY (`cno`) REFERENCES `course` (`cid`)) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;/*!40101 SET character_set_client = @saved_cs_client */;---- Dumping data for table `stu_cour`--LOCK TABLES `stu_cour` WRITE;/*!40000 ALTER TABLE `stu_cour` DISABLE KEYS */;INSERT INTO `stu_cour` VALUES (1,1,1,85),(2,1,3,72),(3,2,2,82),(4,2,3,65),(5,3,1,71),(6,3,2,75),(7,3,3,68),(8,4,1,72),(9,4,2,64),(10,5,2,91),(11,5,3,82),(12,6,1,74),(13,6,2,48),(14,7,2,73),(15,7,3,72),(16,8,1,65),(17,8,2,80),(18,9,1,81),(19,9,2,91),(20,9,3,78);/*!40000 ALTER TABLE `stu_cour` ENABLE KEYS */;UNLOCK TABLES;---- Table structure for table `student`--DROP TABLE IF EXISTS `student`;/*!40101 SET @saved_cs_client     = @@character_set_client */;/*!40101 SET character_set_client = utf8 */;CREATE TABLE `student` (  `sid` int(11) NOT NULL AUTO_INCREMENT,  `sname` varchar(20) DEFAULT NULL,  `sex` varchar(10) DEFAULT NULL,  `birthday` date DEFAULT NULL,  `cno` int(11) DEFAULT NULL,  PRIMARY KEY (`sid`),  KEY `fk_student_001` (`cno`),  CONSTRAINT `fk_student_001` FOREIGN KEY (`cno`) REFERENCES `classes` (`cid`)) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;/*!40101 SET character_set_client = @saved_cs_client */;---- Dumping data for table `student`--LOCK TABLES `student` WRITE;/*!40000 ALTER TABLE `student` DISABLE KEYS */;INSERT INTO `student` VALUES (1,'張三','男','1990-09-01',1),(2,'李四','女','1991-02-13',1),(3,'王五','男','1990-03-12',1),(4,'趙六','男','1992-02-12',2),(5,'田七','男','1994-05-21',2),(6,'張五','女','1990-06-17',2),(7,'張老七','女','1990-04-12',3),(8,'王老四','女','1990-07-16',3),(9,'李六','男','1990-09-12',NULL);/*!40000 ALTER TABLE `student` ENABLE KEYS */;UNLOCK TABLES;/*!40103 SET [email protected]_TIME_ZONE */;/*!40101 SET [email protected]_SQL_MODE */;/*!40014 SET [email protected]_FOREIGN_KEY_CHECKS */;/*!40014 SET [email protected]_UNIQUE_CHECKS */;/*!40101 SET [email protected]_CHARACTER_SET_CLIENT */;/*!40101 SET [email protected]_CHARACTER_SET_RESULTS */;/*!40101 SET [email protected]_COLLATION_CONNECTION */;/*!40111 SET [email protected]_SQL_NOTES */;

相關推薦

MYSQL_2 關係 事務 一對 sql練習

 多表設計之外來鍵約束     約束     約束的作用        約束是用來保證資料的完整性。 單表約束 主鍵約束 唯一約束 非空約束 多表約束 外來鍵約束:用來保證資料完整性(多表之間)。演示外來鍵約束作用建立一個部門表 create table dept( did

精選執行緒面試題目和答案,執行緒理解不是很到位的快來看了~

多執行緒,相信對於很多小白來說是噩夢一般的東西吧,別怕,接下來我們就來把多執行緒的一些面試題一一解讀,希望讀完這篇文章之後,能夠對多執行緒有一個更深入的瞭解。 1. 多執行緒使用的優缺點? 優點: (1)多執行緒技術使程式的響應速度更快 (2)當前沒有進行處理的任務可以將處理器時間讓

hibernate關係配置——一對

如:訂單表與訂單項表 訂單表對應的實體類 (與訂單項表為一對多的關係) private Integer orderId; private String orderNo; /* * 在描述關係的時候,一定是集合介面進行接受 * 對應的訂單詳情一對多關係 *

用SQLAlchemy建立一對關係

多對多關係表的建立: 如果建立好多對多關係後,我們就可以通過關係名進行迴圈查詢,比如laowang = Teacher.query.filter(Teacher.name=='laowang').first().classes[0].teachers, 表示查詢老師表中名為老王的所有教的班級中教第一個班級

Hibernate_day03---關係建立、一對配置及操作、配置及操作

一、表與表關係建立思路 一對多關係 關係舉例: (1)分類和商品關係。 一個分類裡面有多個商品,一個商品只能屬於一個分類 (2)公司和員工關係 一個公司有多個員工,每個員工屬於一個公司 一對多建表:通過外來鍵建立關係 圖示: 多對多關係 關係舉例

JDBC上關於資料庫中操作一對關係關係的實現方法--轉

  原文地址---- https://www.cnblogs.com/pangguoming/p/7028322.html 黑馬程式設計師 我們知道,在設計一個Java bean的時候,要把這些BEAN 的資料存放在資料庫中的表結構,然而這些資料庫中的表直接又有些特殊

JPA關聯關係(一、一對、一對一)

小提示:外來鍵在哪邊,那邊就是多方哦!! 單向多對一:   給多方加上 @ManyToOne ex:【產品類Product--多方 ,產品分類ProductDir--一方】 單向一對多:給一方加上 @OneToMany ex

什麼是實體表,什麼是關係一對應該怎麼設計

    這裡是修真院後端小課堂,每篇分享文從 【背景介紹】【知識剖析】【常見問題】【解決方案】【編碼實戰】【擴充套件思考】【更多討論】【參考文獻】 八個方面深度解析後端知識/技能,本篇分享的是: 【什麼是實體表,什麼是關係表,一對多和多對多應該怎麼設計表?

jpa關係 一對 一對一 註解怎麼寫

一、多表關係 1、一對多        一方放棄外來鍵維護,多方來維護,預設雙方都有外來鍵維護權力,一方選擇放棄就行,避免重複更新 提高效能         多方表加入外來鍵欄位,該欄位值和一方

# Mybatis(四)關係分析,高階對映(一對一,一對) 菜鳥日記--day05(下_02)

Mybatis(四)表間關係分析,高階對映(一對一,一對多,多對多) 菜鳥日記–day05(下_02) 花了很多時間,去看sql複雜查詢,更新慢了 電腦斷電寫的太急,綠色補更 一、表間關係分析 1.分析資料庫表的方法 思路: 需要分模組的對多張表進行邏輯分析 表記錄

jpa關係 一對 一對一 註解怎麼寫

一、多表關係 1、一對多        一方放棄外來鍵維護,多方來維護,預設雙方都有外來鍵維護權力,一方選擇放棄就行,避免重複更新 提高效能         多方表加入外來鍵欄位,該欄位值和一方表id一致,但外來鍵欄位在實體中並沒有宣告屬性,也就是說多方實體內沒有外來鍵

五、hibernate之間的關係一對關係

資料庫表與表之間的關係 一對多:一個學校可以有多個學生,一個學生只能有一個學校 多對多:一個學生可以有多個老師,一個老師可以教多個學生 一對一:一個人只能有一個身份證號,一個身份證號只能找到一個人 一對多關係 建立學生和學校表 create table school( sc

資料庫中表與之間建立關係一對

一、一對多的關係 例:公司與員工的關係,公司為一,公司員工為多,需要在多方建立外來鍵指向一方的主鍵。 一對多讓兩個實體類之間相互表示 (1)一個公司裡面有多個員工。 private Set<yuangong> yuangongSet=new HashSet

057:關係一對

表關係:表之間的關係都是通過外來鍵來進行關聯的。而表之間的關係,無非就是三種關係:一對一、一對多(多對一)、多對多等。以下將討論一下三種關係的應用場景及其實現方式。 一對多:1. 應用場景:比如文章和作者之間的關係。一個文章只能由一個作者編寫,但是一個作者可以寫多篇文章。文章和作者之間的關係就是典型的多對一

間的關係一對/一對一/關係是怎樣建立的?

外來鍵可以是一對一的,一個表的記錄只能與另一個表的一條記錄連線,或者是一對多的,一個表的記錄與另一個表的多條記錄連線。 1.一對多,在多的一方建立外來鍵(外來鍵指向一的主鍵) 母親與孩子的關係:母親,孩子兩個實體 母親表:ID(P),名字,年齡,性別 孩子表:ID(P)

關係:一對

一對多和多對一 java實體中的表現形式 public class ClassEntity {//班級的實體類 private String classId; private String className; private Set&l

資料對應關係(一對一、一對

1.資料庫中的多對多關聯關係一般需採用中間表的方式處理,將多對多轉化為兩個一對多。2.通過表的關係,來幫助我們怎樣建表,建幾張表。一對一一張表的一條記錄一定只能與另外一張表的一條記錄進行對應,反之亦然。學生表:姓名,性別,年齡,身高,體重,籍貫,家庭住址,緊急聯絡人其中姓名、性別、年齡、身高,體重屬於常用資料

資料庫的關係一對例項

一個專案對應多個學生 一個學生對應多個專案(多對多關係) 專案表 學生表 專案號(主) 學生號(主) 學生-專案表 專案號(外) 學生號(外) 實現多對多關係,必須要第三表來操作,且它們都屬於外來鍵。 一個導師對應多個專案 一個專案對應一個老師(一對多關係)

row_number() over 兩連線分頁SQL 一對關係 去重

--總條數 SELECT COUNT(1) FROM dbo.osaleh INNER JOIN dbo.osaled ON dbo.osaleh.osaleh_osalehID=dbo.osaled.osaled_osalehID WHERE --兩表連線分頁

sqlalchemy 關係一對

session.add(arctire)session.commit()測試資料是否插入成功OK,由上圖可知,資料已成功插入到表中。接下來,我們想通過文章(arcitre)表查詢到使用者名稱(name),先來使用一個比較笨的方法(程式碼如下所示)arctire = session.query(Arctire)