關(guān)系數(shù)據(jù)庫(kù)概述
- 數(shù)據(jù)持久化 - 將數(shù)據(jù)保存到能夠長(zhǎng)久保存數(shù)據(jù)的存儲(chǔ)介質(zhì)中,在掉電的情況下數(shù)據(jù)也不會(huì)丟失。
將數(shù)據(jù)寫(xiě)入到文件;缺點(diǎn):不方便取出數(shù)據(jù)和查找數(shù)據(jù) 。
用Excel表格;缺點(diǎn):不方便查找和修改數(shù)據(jù)。
數(shù)據(jù)庫(kù)管理系統(tǒng)
-
數(shù)據(jù)庫(kù) - 數(shù)據(jù)的集散地(倉(cāng)庫(kù))
優(yōu)點(diǎn):不僅可以保存數(shù)據(jù),更重要的是能夠很好的管理數(shù)據(jù),方便將來(lái)對(duì)數(shù)據(jù)的檢索,大多數(shù)的數(shù)據(jù)庫(kù)都能夠保證數(shù)據(jù)的一致性、完整性并減少數(shù)據(jù)的冗余
數(shù)據(jù)庫(kù)發(fā)展史 - 網(wǎng)狀數(shù)據(jù)庫(kù)、層次數(shù)據(jù)庫(kù)、關(guān)系數(shù)據(jù)庫(kù)、NoSQL數(shù)據(jù)庫(kù)。
1970s,IBM的研究員E.F.Codd在Communication of the ACM上發(fā)表了名為A Relational Model of Data for Large Shared Data Banks的論文,提出了關(guān)系模型的概念,奠定了關(guān)系模型的理論基礎(chǔ)。后來(lái)Codd又陸續(xù)發(fā)表多篇文章,論述了范式理論和衡量關(guān)系系統(tǒng)的12條標(biāo)準(zhǔn),用數(shù)學(xué)理論奠定了關(guān)系數(shù)據(jù)庫(kù)的基礎(chǔ)。
- 關(guān)系數(shù)據(jù)庫(kù)的特點(diǎn)
理論基礎(chǔ):集合論和關(guān)系代數(shù)。
具體表象:用二維表(行 - 記錄 列 - 字段)組織數(shù)據(jù)。
理論基礎(chǔ):集合論和關(guān)系代數(shù)。
MySQL簡(jiǎn)介
MySQL最早是由瑞典的MySQL AB公司開(kāi)發(fā)的一個(gè)開(kāi)放源碼的關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng),該公司于2008年被昇陽(yáng)微系統(tǒng)公司(Sun Microsystems)收購(gòu)。在2009年,甲骨文公司(Oracle)收購(gòu)昇陽(yáng)微系統(tǒng)公司,因此在這之后MySQL成為了Oracle旗下產(chǎn)品。
MySQL在過(guò)去由于性能高、成本低、可靠性好,已經(jīng)成為最流行的開(kāi)源數(shù)據(jù)庫(kù),因此被廣泛地應(yīng)用于中小型網(wǎng)站開(kāi)發(fā)。隨著MySQL的不斷成熟,它也逐漸被應(yīng)用于更多大規(guī)模網(wǎng)站和應(yīng)用,比如維基百科、谷歌(Google)、臉書(shū)(Facebook)、淘寶網(wǎng)等網(wǎng)站都使用了MySQL來(lái)提供數(shù)據(jù)持久化服務(wù)。
甲骨文公司收購(gòu)后昇陽(yáng)微系統(tǒng)公司,大幅調(diào)漲MySQL商業(yè)版的售價(jià),且甲骨文公司不再支持另一個(gè)自由軟件項(xiàng)目OpenSolaris的發(fā)展,因此導(dǎo)致自由軟件社區(qū)對(duì)于Oracle是否還會(huì)持續(xù)支持MySQL社區(qū)版(MySQL的各個(gè)發(fā)行版本中唯一免費(fèi)的版本)有所擔(dān)憂,MySQL的創(chuàng)始人麥克爾·維德紐斯以MySQL為基礎(chǔ),成立分支計(jì)劃MariaDB(以他女兒的名字命名的數(shù)據(jù)庫(kù))。有許多原來(lái)使用MySQL數(shù)據(jù)庫(kù)的公司(例如:維基百科)已經(jīng)陸續(xù)完成了從MySQL數(shù)據(jù)庫(kù)到MariaDB數(shù)據(jù)庫(kù)的遷移。
安裝和配置(在CentOS7 Linux環(huán)境下)
- MySQL有一個(gè)分支版本名叫MariaDB,它們的底層庫(kù)是沖突的,要安裝MySQL,必須先保證系統(tǒng)中沒(méi)有MariaDB相關(guān)的文件。如果系統(tǒng)上有MariaDB相關(guān)的文件,需要先移除MariaDB相關(guān)的文件。
yum list installed | grep mariadb | awk '{print $1}' | xargs yum erase -y
- 下載
wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.26-1.el7.x86_64.rpm-bundle.tar
- 解歸檔
tar -xvf mysql-5.7.26-1.el7.x86_64.rpm-bundle.tar
- 接下來(lái)可以按照如下所示的順序用RPM(Redhat Package Manager)工具安裝MySQL。
rpm -ivh mysql-community-common-5.7.26-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-5.7.26-1.el7.x86_64.rpm
rpm -ivh mysql-community-client-5.7.26-1.el7.x86_64.rpm
rpm -ivh mysql-community-server-5.7.26-1.el7.x86_64.rpm
- 接下來(lái)啟動(dòng)MySQL服務(wù)器
啟動(dòng)服務(wù)器:
systemctl start mysqld / service mysqld start
關(guān)閉服務(wù)器:
systemctl stop mysqld / service mysqld stop
重啟服務(wù)器:
systemctl restart mysqld
- 查看運(yùn)行狀態(tài)和網(wǎng)絡(luò)狀態(tài)
systemctl status mysqld
netstat -ntlp | grep mysql
- 在日志文件中找出root用戶的臨時(shí)密碼
cat /var/log/mysqld.log | grep "A temporary password"
- 通過(guò)MySQL客戶端工具連接服務(wù)器
mysql -uroot -p
- 輸入臨時(shí)密碼進(jìn)入,此時(shí)不能做任何事情,因?yàn)镸ySQL默認(rèn)必須修改密碼之后才能操作數(shù)據(jù)庫(kù):
ALTER USER 'root'@'localhost' IDENTIFIED BY '新密碼';
這里有個(gè)問(wèn)題,新密碼設(shè)置的時(shí)候如果設(shè)置的過(guò)于簡(jiǎn)單會(huì)報(bào)錯(cuò);原因是因?yàn)镸ySQL有密碼設(shè)置的規(guī)范,具體是與validate_password_policy的值有關(guān),可以降低密碼強(qiáng)度。
- 密碼強(qiáng)度設(shè)為最低,長(zhǎng)度為6,就可以修改密碼了
set global validate_password_policy=0;
set global validate_password_length=6;
ALTER USER 'root'@'localhost' IDENTIFIED BY '新密碼';
- 此時(shí)的root用戶是沒(méi)有權(quán)限的,接下來(lái)創(chuàng)建遠(yuǎn)程連接用戶并賦予用戶權(quán)限
create user 'root'@'%' identified by '123456';
grant all privileges on *.* to 'root'@'%' with grant option;
- 刷新權(quán)限
flush privileges;
常用命令
- 查看服務(wù)器版本
select version();
- 查看當(dāng)前所有數(shù)據(jù)庫(kù)
show databases;
- 切換到指定數(shù)據(jù)庫(kù)
use 數(shù)據(jù)庫(kù)名;
- 查看當(dāng)前數(shù)據(jù)庫(kù)下所有表
show tables;
- 查看當(dāng)前使用的數(shù)據(jù)庫(kù)
select database();
- 查看表的結(jié)構(gòu)
desc 表名;
- 查看當(dāng)前用戶
select user();
- 查看當(dāng)前時(shí)間
select now();
- 顯示數(shù)據(jù)庫(kù)的創(chuàng)建和數(shù)據(jù)表的創(chuàng)建
show create database 數(shù)據(jù)庫(kù)名;
show create table 數(shù)據(jù)表名;
- 獲取幫助
? contents;
? functions;
? numeric functions;
? round;
? data types;
? longblob;
SQL基本語(yǔ)法
我們通常可以將SQL分為三類:DDL(數(shù)據(jù)定義語(yǔ)言)、DML(數(shù)據(jù)操作語(yǔ)言)和DCL(數(shù)據(jù)控制語(yǔ)言)。
DDL主要用于創(chuàng)建(create)、刪除(drop)、修改(alter)數(shù)據(jù)庫(kù)中的對(duì)象,比如創(chuàng)建、刪除和修改二維表;
DML主要負(fù)責(zé)插入數(shù)據(jù)(insert)、刪除數(shù)據(jù)(delete)、更新數(shù)據(jù)(update)和查詢(select);
DCL通常用于授予權(quán)限(grant)和召回權(quán)限(revoke)。
說(shuō)明:SQL是不區(qū)分大小寫(xiě)的語(yǔ)言;每條SQL語(yǔ)句必須以分號(hào)結(jié)束
DDL - 數(shù)據(jù)定義語(yǔ)言
-- 0. 刪除數(shù)據(jù)庫(kù): drop database 數(shù)據(jù)庫(kù)名;
DROP DATABASE school; -- 直接刪除指定數(shù)據(jù)庫(kù)
DROP DATABASE if EXISTS school; -- 如果指定的數(shù)據(jù)庫(kù)存在就刪除數(shù)據(jù)庫(kù)
-- 1.創(chuàng)建數(shù)據(jù)庫(kù): create database 數(shù)據(jù)庫(kù)名;
create database school; -- 直接創(chuàng)建指定數(shù)據(jù)庫(kù)
CREATE database if not EXISTS school;
-- 當(dāng)指定數(shù)據(jù)庫(kù)不存在的時(shí)候才創(chuàng)建數(shù)據(jù)庫(kù)
create database if not EXISTS school default charset utf8;
-- 創(chuàng)建數(shù)據(jù)庫(kù)的時(shí)候設(shè)置字符集編碼方式為utf8,讓數(shù)據(jù)庫(kù)支持中文數(shù)據(jù)的存儲(chǔ)
-- 2.使用/切換/數(shù)據(jù)庫(kù): use 數(shù)據(jù)庫(kù)名;
use school;
-- 3.新建表: create table if not exists 表名(字段名1 類型1, 字段2 類型2,...);
-- 注意: a. 表名一般需要加前綴't'或者'tb'
b.字段用來(lái)確定表中要存儲(chǔ)哪些數(shù)據(jù),字段名隨便命名但是不能是關(guān)鍵字
c.數(shù)據(jù)類型必須是MySQL支持的數(shù)據(jù)類型
-- 常用數(shù)據(jù)類型: int-整數(shù), char(size)-定長(zhǎng)字符串, varchar(size)-不定長(zhǎng)字符串, text-字符串, bit-布爾, date-日期
CREATE TABLE if not EXISTS t_student(stuid int, stuname varchar(20), gender bit, birth date);
-- 新建表并且添加約束: create table if not exists 表名(字段名1 類型1 約束1, 字段2 類型2 約束2,...);
-- 常見(jiàn)約束: not null - 不為空, default - 設(shè)置默認(rèn)值, unique - 值唯一, primary key - 主鍵約束 , foregin key - 外鍵約束
-- 主鍵約束: 主鍵的值可以確定列表中唯一一條記錄(通過(guò)一個(gè)主鍵值可以找到表中的唯一一條記錄)
-- 注意: auto_increment只針對(duì)主鍵有效,并且主鍵的類型是整型;
CREATE TABLE if not EXISTS t_student
(
stuid int not null auto_increment,
stuname varchar(20) not null,
gender bit DEFAULT 1,
birth date,
PRIMARY KEY(stuid) -- 將字段stuid作為當(dāng)前表的主鍵(設(shè)置主鍵可以間接約束這個(gè)字段的值是唯一的)
);
-- 4.刪除表: DROP TABLE if EXISTS 表名;
DROP TABLE if EXISTS t_student;
-- 清空表中的數(shù)據(jù): TRUNCATE TABLE 表名;
TRUNCATE TABLE t_student;
-- 5.修改表
-- 5.1 添加列: alter TABLE 表名 add COLUMN 字段名 字段類型 約束;
alter TABLE t_student add COLUMN score FLOAT(8,2) DEFAULT 0;
alter TABLE t_student add COLUMN addr VARCHAR(100);
-- 5.2 刪除列: alter TABLE 表名 drop COLUMN 字段名;
alter TABLE t_student drop COLUMN gender;
-- 5.3 修改列: alter TABLE 表名 modify 字段名 字段類型 約束; (不重命名)
-- 修改列: alter TABLE 表名 change 原字段名 新字段名 字段類型 約束; (重命名)
-- =============補(bǔ)充==============
-- 常見(jiàn)數(shù)據(jù)類型:
-- varchar(size) - 不定長(zhǎng)字符串,size決定的是最大長(zhǎng)度
-- char(size) - 定長(zhǎng)字符
-- text - 不限長(zhǎng)度(最大是255個(gè)字符)
-- int/tinyint - 整型 (-128~127)
-- FLOAT(size,d)/DOUBLE(size,d) - 小數(shù),size-總長(zhǎng)度, d-小數(shù)部分長(zhǎng)度
-- bit - 布爾,只有0或1
-- date/datetime/time - 值可以是時(shí)間函數(shù)的結(jié)果,也可以時(shí)間字符串;計(jì)算或者是比較的時(shí)候內(nèi)部是按時(shí)間處理的
DML - 數(shù)據(jù)操作語(yǔ)言
-- 1.增(添加數(shù)據(jù)/記錄)
-- 1.1插入數(shù)據(jù)/記錄: insert into 表名 values(值1, 值2, 值3,....) - 依次給指定表中的字段賦值
INSERT into t_student VALUES(100, '張三', 0, '2019-9-23');
-- 1.2插入數(shù)據(jù)/記錄: insert into 表名(字段名1,字段名2,...) values(值1, 值2,...) -以指定的順序給指定的字段賦值
-- 一次插入一條記錄
INSERT into t_student(stuname, birth) VALUES("小花", date(now()));
-- 一次插入多條記錄
INSERT into t_student(stuname, birth) VALUES
("小花", date(now())),
('小明', '2018-9-8'),
('路飛', '1999-12-16'),
('佐助', '2000-10-12');
-- 值的問(wèn)題: sql中是數(shù)字對(duì)應(yīng)的值直接寫(xiě),字符串需要使用引號(hào)引起來(lái),bit類型的值只有0或者1, 時(shí)間可以用內(nèi)容是滿足時(shí)間格式字符串也可以是通過(guò)時(shí)間函數(shù)獲取的值
-- 時(shí)間函數(shù): now() - 當(dāng)前時(shí)間 date(now()) - 當(dāng)前日期 year(now()) - 當(dāng)前年 month(now()) - 當(dāng)前月 ....
-- 2.刪(刪除數(shù)據(jù)/記錄)
-- delete from 表名; - 刪除指定表中所有記錄
DELETE FROM t_student;
-- delete from 表名 where 條件語(yǔ)句; - 刪除滿足條件的記錄
-- SQL中的條件語(yǔ)句: =(判斷是否相等), <>(不等于,和python中的!=功能一樣), >, <, >=, <=
DELETE FROM t_student WHERE stuid=100;
-- 刪除t_student表中stuid的值等于100的記錄
DELETE FROM t_student WHERE stuname='小花';
-- 刪除t_student表中stuname的值等于'小花'的記錄
DELETE FROM t_student WHERE stuid<108;
-- 刪除t_student表中stuid的值小于108的記錄
-- 3.改(修改數(shù)據(jù)/記錄)
-- update 表名 set 字段1=新值1, 字段2=新值2,...; - 將指定表中所有行的指定列/字段的值賦值為新值
UPDATE t_student set birth='1999-10-1', gender=1;
-- update 表名 set 字段1=新值1, 字段2=新值2,... where 條件語(yǔ)句; -將表中滿足條件的行中指定字段的值賦值為新值
UPDATE t_student set gender=0 WHERE stuname='小花';
-- 通配符%: 表示任意個(gè)數(shù)的任意字符(包括0個(gè))
UPDATE t_student set birth='2000-01-01' WHERE stuname LIKE '小%';
-- 修改stuname是以'小'開(kāi)頭的行對(duì)應(yīng)的birth的值
UPDATE t_student set birth='2111-01-01' WHERE stuname LIKE '%小%';
-- 統(tǒng)配符_: 表示一個(gè)任意字符
UPDATE t_student set birth='2444-01-01' WHERE stuname LIKE '小_'; -- 修改stuname只有兩個(gè)字符,并且第一個(gè)字符是‘小’對(duì)應(yīng)的行的birth的值
-- 注意: 通配符只針對(duì)字符串有效!
-- 4.查(獲取數(shù)據(jù))
-- 4.1直接查詢
-- select * from 表名; - 獲取指定表中所有行和所有的列(所有數(shù)據(jù))
SELECT * FROM t_student;
-- select 字段名1,字段名2,... from 表名; - 獲取指定表中所有行指定的列
SELECT stuname,stuid FROM t_student;
-- select * from 表名 where 條件; - 獲取指定表中所有滿足條件的行所有列的數(shù)據(jù)
SELECT * FROM t_student WHERE stuid>115;
-- 4.2列重命名
-- select 字段1 as 新字段1, 字段2 as 新字段2,... from 表名;
-- 注意: 這兒的as可以省略
SELECT stuid as '學(xué)號(hào)', stuname, gender as '性別' FROM t_student;
-- 對(duì)查詢結(jié)果中的stuid和gender字段進(jìn)行重命名
-- 4.3對(duì)查詢結(jié)果重新賦值(一般針對(duì)布爾數(shù)據(jù))
-- select if(字段名,值1,值2) from 表名; -查詢指定字段,并且判斷字段對(duì)應(yīng)的值是0還是1,如果是1結(jié)果為值1,否則為值2
-- 注意: 這兒的if的用法是MySQL專有的
-- MySQL寫(xiě)法: if(字段, 新值1, 新值2)
SELECT stuname,if(gender,'男','女') as '性別' FROM t_student;
-- 通用寫(xiě)法: case 字段 when 值 then 新值1 else 新值2 end
SELECT case gender WHEN 1 THEN '男' ELSE '女' END as '性別' FROM t_student;
-- 4.4對(duì)列進(jìn)行合并
-- select concat(字段1,字段2,...) from 表名;
SELECT CONCAT(stuname,stuid) as 'name_id' FROM t_student;
SELECT CONCAT(stuname,':',stuid) as 'name_id' FROM t_student;
-- 注意: 數(shù)字和字符串?dāng)?shù)據(jù)可以合并,bit類型的數(shù)據(jù)不可以合并
-- SELECT CONCAT(stuname,':',gender) as 'name_id' FROM t_student;
-- 4.5模糊查詢 - 查詢的時(shí)候時(shí)候通過(guò)like條件來(lái)指定查詢對(duì)象
-- sql中支持邏輯運(yùn)算符and(邏輯與運(yùn)算)和or(邏輯或運(yùn)算),not(邏輯非)
SELECT * FROM t_student WHERE stuname like '%飛%' or not stuid < 110;
-- 4.6排序(先按之前的任何語(yǔ)法進(jìn)行查詢?cè)谂判?
-- select * from 表名 order by 字段; - 對(duì)查詢結(jié)果按照指定字段的值進(jìn)行升序排序
-- select * from 表名 order by 字段 asc; - 對(duì)查詢結(jié)果按照指定字段的值進(jìn)行升序排序
-- select * from 表名 order by 字段 desc; - 對(duì)查詢結(jié)果按照指定字段的值進(jìn)行降序排序
SELECT * FROM t_student ORDER BY gender; -- 按性別升序排序
SELECT * FROM t_student ORDER BY stuid ASC; -- 按學(xué)號(hào)升序排序
SELECT * FROM t_student ORDER BY stuid DESC; -- 按學(xué)號(hào)降序排序
-- =============補(bǔ)充==============
-- 條件語(yǔ)句的寫(xiě)法:
-- 在SQL中可以通過(guò) `where 條件語(yǔ)句`來(lái)對(duì)操作對(duì)象進(jìn)行篩選 - 篩選
-- a. 比較運(yùn)算符: =, <>, >, <, >=, <=
-- 注意: 判斷一個(gè)字段的值是否為空不用使用=和<>(不等與), 而是使用`is null` 和 `is not null`
SELECT addr FROM t_student;
SELECT stuname FROM t_student WHERE addr is NULL; -- 判斷是否為NULL(空)
SELECT stuname FROM t_student WHERE addr<=>NULL; -- 判斷是否為NULL(空)
SELECT stuname FROM t_student WHERE addr=''; -- 判斷是否是空串
-- b. 邏輯運(yùn)算符: and, or, not
-- c. where 字段名 between 值1 and 值2 -- 篩選指定的字段的值在值1和值2之間
SELECT stuname,birth FROM t_student WHERE birth BETWEEN '1990-1-1' AND '1999-12-31';
-- d. where 字段名 in 集合 -- 篩選出字段值是集合中的元素;(集合是使用括號(hào)括起來(lái)里面多個(gè)值)
SELECT * FROM t_student WHERE stuname in ('小花', '小明', '路飛');
-- e. like操作
DCL - 數(shù)據(jù)控制語(yǔ)言
-- 創(chuàng)建可以遠(yuǎn)程登錄的root賬號(hào)并為其指定口令
create user 'root'@'%' identified by '123456';
-- 刪除用戶 - drop user 用戶名;
drop user zhangsan;
-- 為遠(yuǎn)程登錄的root賬號(hào)授權(quán)操作所有數(shù)據(jù)庫(kù)所有對(duì)象的所有權(quán)限并允許其將權(quán)限再次賦予其他用戶
grant all privileges on *.* to 'root'@'%' with grant option;
-- 創(chuàng)建名為hellokitty的用戶并為其指定口令
create user 'hellokitty'@'%' identified by '123123';
-- 將對(duì)school數(shù)據(jù)庫(kù)所有對(duì)象的所有操作權(quán)限授予hellokitty
grant all privileges on school.* to 'hellokitty'@'%';
-- 召回hellokitty對(duì)school數(shù)據(jù)庫(kù)所有對(duì)象的insert/delete/update權(quán)限
revoke insert, delete, update on school.* from 'hellokitty'@'%';