1. 程式人生 > >MySQL數據庫:SQL語句基礎、庫操作、表操作、數據類型、約束條件、表之間的關系

MySQL數據庫:SQL語句基礎、庫操作、表操作、數據類型、約束條件、表之間的關系

顯示 sel 不為 完整性 查看 步長 utf condition 情況下

數據庫相關概念:

1. 數據庫服務器:運行數據庫管理軟件的計算機

2. 數據庫管理軟件:MySQL、Oracle、db2、slqserver

3. 庫:文件夾,用來組織文件/表

4. 表:文件(類似於excel),用來存放多行內容/多條記錄

5. 記錄:事物一系列典型的特征

6. 數據:描述事物特征的符號

MySQL數據庫就是一個套接字軟件,用來管理其他機器上的數據文件

MySQL介紹:

MySQL是一個關系型數據庫管理系統;就是一個基於socket編寫的C/S架構胡軟件

客戶端軟件

  mysql自帶:如mysql命令,mysqldump命令等

  python模塊:如pymysql

數據庫管理軟件分類:

分兩大類:

  關系型:如 sqllite,db2,oracle,access,sql server,mysql,註意:sql語句通用

  非關系型:mongodb,redis,memcache

可以簡單的理解為:

  關系型數據庫需要有表結構

  非關系型數據庫是key-value存儲的,沒有表結構

SQL語句基本操作:

MySQL服務端軟件即mysqld幫我們管理好文件夾及文件,前提是作為使用者的我們,需要下載mysql的客戶端,或者其他模塊來連接到mysqld,然後使用mysql軟件規定的語法格式去提交自己的命令,實現對文件夾或文件的管理。該語句即sql(Structured Query Language 結構化查詢語言)

SQL語言主要用於存取數據、查詢數據、更新數據和管理關系數據庫系統;分為3種類型:

1. DDL語句:  數據庫定義語言:數據庫、表、視圖、索引、存儲過程,例如create,drop,alter

2. DML語句:  數據庫操縱語言:插入數據insert、刪除數據delete、更新數據update、查詢數據select

3. DCL語句:  數據庫控制語言:例如控制用戶胡訪問權限grant、revoke

操作文件夾(庫)

  增: create database db1 charset utf8; (創建數據庫db1,其字符編碼為UTF-8;db1是庫名)

  查: show create database db1;

(查看我剛創建的文件夾db1)

     show databases; (查看所有的數據庫)

  改: alter database db1 charset gbk; (改數據庫 db1 的字符編碼 為 gbk; 不能改名字,只能改字符編碼)

  刪: drop database db1; (刪數據庫db1)

操作文件(表)

  先切換文件夾: use db1; (切換到數據庫db1)

  查看當前所在的文件夾(庫): select database();

  增: create table t1(id int,name char); (創建文件(表),文件名是t1,表中字段是id(id的數據類型是整型) 和 name(name是字符))

  查: show create table t1; (查看創建的文件t1)

     desc t1; (查看表t1;desc是describe的縮寫)

     show tables; (查看當前庫下所有的表/文件)

  改: alter table t1 modify name char(6); (修改表t1,把t1中name字段char的寬度改為6)

     alter table t1 change name NAME char(7); (修改表t1,把t1中name字段改為NAME,並把char改為7)

  刪: drop table t1; (刪除t1這個表)

操作文件內容(記錄)

  增:insert t1(id,name) values(1,"neo1"),(2,"neo2"),(3,"neo3"); (往t1這個文件中插入values;插入多條value用逗號隔開;values中的值按照t1後面的字段順序添加)

    insert t1 values(1,"neo1"),(2,"neo2"),(3,"neo3"); (t1後面不加字段名,默認按字段順序添加values)

  查:select id,name from t1; (查看當前庫下t1這個表的id和name)

    select id,name from db1.t1; (如果所查看的t1表不在當前庫下,則在t1前加上db1這個庫名前綴)

    select id from t1; (只查詢id)

    select * from t1; (查詢所有字段)

  改:update db1.t1 set name="NEO"; (更改db1庫下的t1表,把name字段全部設置成NEO)

    update t1 set name="Neo" where id=2; (更新當前庫下的t1表,把id為2那一行name設置成Neo)

  刪:delete from t1; (把t1表下的所有記錄都刪除)

    delete from t1 where id=2; (把t1表下id為2的記錄刪除)

庫操作:

系統數據庫:

information_schema:虛擬庫,不占用磁盤空間,存儲的是數據庫啟動後的一些參數,如用戶表信息、列信息、權限信息、字符信息等

performance_schema:MySQL 5.5開始新增一個數據庫:主要用於收集數據庫服務器性能參數,記錄處理查詢請求時發生的各種事件、鎖等現象

mysql:授權庫,主要存儲系統用戶胡權限信息

test:MySQL數據庫系統自動創建胡測試數據庫

創建數據庫:

1. 語法: create database 數據庫名 charset utf8;

2. 數據庫命名規則:

  可以由字母、數字、下劃線、@、#、¥

  區分大小寫

  唯一性

  不能使用關鍵字如create、select等

  不能單獨使用數字

  最長128位

數據庫相關操作:

  查看數據庫:

    show databases;

    show create database db1;

    select database();

  選擇數據庫:

    use 數據庫名;

  刪除數據庫:

    drop database 數據庫名;

  修改數據庫:

    alter database db1 charset utf8;

存儲引擎介紹:

1. 數據庫中的表有不同胡類型,表的類型不同,會對應mysql不同的存取機制,表類型又稱存儲引擎;存儲引擎就是表的類型

2. 查看MySQL支持的存儲引擎: show engines; # 默認的存儲引擎是innodb

3. 指定表類型/存儲引擎:

  create table t1(id int)engine=innodb;

  create table t1(id int)engine=memory;

  create table t1(id int)engine=blackhole;

表操作:

1. 表介紹:表相當於文件,表中的一條記錄就相當於文件胡一行內容,不同的是,表中的一條記錄有對應的標題,稱為表的字段

技術分享圖片

id,name,age,sex稱為字段,其余的,一行內容稱為一條記錄

2. 創建表:

語法:

  create table 表名(

  字段名1 類型[(寬帶)約束條件],

  字段名2 類型[(寬帶)約束條件],

  字段名3 類型[(寬帶)約束條件]

  ) ;

附:表中最後一個字段後面不要再加逗號

註意:

  1. 同一張表種,字段名不能相同

  2. 寬帶和約束條件可選

  3. 字段名肯類型椒必須的

3. 查看表結構:

  1. describe 表名; # 查看表結構,可簡寫為 desc 表名;

  2. show create table 表名; # 查看表詳細結構,可加 \G

4. 修改表結構:

  1. 修改表名: alter table 表名 rename 新表名;

  2. 增加字段: alter table 表名 add 字段名 數據類型 [完整性約束條件], add 字段名 數據類型 [完整性約束條件];

         alter table 表名 add 字段名 數據類型 [完整性約束條件] first; # 把這個字段放到第幾個位置

         alter table 表名 add 字段名 數據類型 [完整性約束條件] after 字段名; # 把新添加的字段放到某個字段後面

  3. 刪除字段: alter table 表名 drop 字段名;

  4. 修改字段: alter table 表名 modify 字段名 數據類型 [完整性約束條件]; # 修改字段的數據類型相關信息

         alter table 表名 change 舊字段名 新字段名 新/舊數據類型 [完整性約束條件]; # 修改字段名和數據類型

5. 刪除表: drop table 表名;

6. 復制表:

  1. 復制表結構和記錄: create table 表名1 select name,age from db1.表名2; # 數據庫db1中的表名2中的name和age復制到表名1中(把表2胡查詢結果當作復制的內容傳給表1)

技術分享圖片

  2. 只復制表結構,不復制紀錄:create table 表名1 select name,age from db1.表名2 where 1>5; # where 1>5是一個假條件(沒有紀錄能滿足這個條件),但表名2的表結構卻是存在的,通過這種方式去只復制表結構

技術分享圖片

  3. 只復制全部的表結構: create table 表名1 like db1.表名2; # 復制db1數據庫中表名2的所有表結構,不復制紀錄

技術分享圖片

數據類型:

存儲引擎決定了表的類型,而表內存放胡數據也要有不同的類型,每種數據類型都有自己的寬帶,但寬度是可選胡

詳細參考:

    http://www.runoob.com/mysql/mysql-data-types.html

    https://dev.mysql.com/doc/refman/5.7/en/data-type-overview.html

MySQL常用數據類型:

  1. 數字

    整形:tinyint, int, bigint

    小數:

      float:在位數比較短的情況下不精確

      double:在位數比較長的情況下不精確

      decimal:精確,內部原理是字符串形式存儲

  2. 字符串:

    char(10):簡單粗暴,浪費空間,存取速度快;root存成root000000

    varchar:精確,節省空間,存取速度慢

  3. 時間類型: 最常用:datetime

  4. 枚舉類型於集合類型

數值類型:

1. 整數類型:tinyint, smallint, mediumint,bigint; 作用:存儲年齡、等級、id、各種號碼等

  tinyint[(m)] [unsigned] [zerofill]

  小整數,數據類型用於保存一些範圍的整數數值範圍:

  有符號: -128~127 ; 無符號: 0~255 ; ps: MySQL中無布爾值,使用tinyint(1)構造

  inyint[(m)] [unsigned] [zerofill]

  整數,數據類型用於保存一些範圍的整數數值範圍:

  有符號:-2147483648 ~ 2147483647;無符號: 0 ~ 4294967295

註意:為整數類型指定寬度時,僅僅只是指定查詢結果的顯示寬度,與存儲範圍無關;其實我們完全沒必要為整數類型指定顯示寬帶,使用默認的就可以了;默認的顯示寬帶,都是在最大值的基礎上加1

技術分享圖片

int的存儲寬度是4個bytes,即32個bit,即2**32; 無符號最大值為:4294967296-1;有符號最大值:2147483648-1

有符號和無符號的最大數字需要的顯示寬度均為10,而針對有符號的最小值則需要11位才能顯示完整,所以int類型默認的顯示寬帶為11是非常合理的;所以,整形類型,沒有必要指定顯示寬度,使用默認的就行

浮點型:定點數類型:decimal(等同於dec); 浮點類型:float,double;作用:存儲薪資、身高、體重、體質參數等

  float[(m,d)] [unsigned] [zerofill]:

    定義:單精度浮點數(非準確小數值),m是數字總個數,d是小數點後個數;m最大值為255,d最大值為30;隨著小數的增多,精度變得不準確

  double[(m,d)] [unsigned] [zerofill]:

    定義:雙精度浮點數(非準確小數值),m是數字總個數,d是小數點後個數。m最大值為255,d最大值為30;隨著小數的增多,精度比float要高,但也會變得不準確

  decimal[(m[,d])] [unsigned] [zerofill]:

    定義: 準確的小數值,m是數字總個數(負號不算),d是小數點後個數。 m最大值為65,d最大值為30;隨著小數的增多,精度始終準確;對於精確數值計算時需要用此類型;decaimal能夠存儲精確值的原因在於其內部按照字符串存儲。

補充知識點:加入一條sql語句寫錯了,可以利用 \c 來終止這條語句的運行; 加入少了一個引號,就先把引號補全再用\c, 如: ‘\c

日期類型:year, date, time, datetime, timestamp;作用:存儲用戶註冊時間、文章發布時間、入職時間、出生時間、過期時間等

形式與範圍:

  year:YYYY(1901/2155)

  date:YYYY-MM-DD (1000-01-01/9999-12-31)

  time:HH:MM:SS(‘-838:59:59‘/‘838:59:59‘)

  datetime: YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59 )

  timestamp:YYYYMMDD HHMMSS(1970-01-01 00:00:00/2037 年某時)

先看下面一段sql語句:

 create table stu1(
                   id int,
                   name char(6),
                   born_year year,
                   birth_date date,
                   class_time time,
                   regis_time datetime
                   );   # char(6)是最多能存儲6個字符,所以名字最多6個字符

 insert stu1 values(1,"neo",now(),now(),now(),now()); # now()是mysql是自帶的一個函數,調用當前時間

執行結果如下:

技術分享圖片

也可以自己添加日期:

insert stu1 values(2,"alex","2007","2007-1-11","08:00:00","2016-1-11 11:11:00"); 

如下圖:

技術分享圖片

字符類型:

char和varchar括號內的參數指的都是字符的長度

char類型:定長,簡單粗暴,浪費空間,存取速度快

  字符長度範圍:0-255 (一個中文是一個字符,是utf8編碼的3個字節)

  存儲:存儲char類型的值時,會往右填充空格來滿足長度,例如:指定長度為10,存<10個字符則用空格填充直到湊夠10個字符存儲

  檢索:在檢索或者說查詢時,查出的結構會自動刪除尾部的空格,除非我們打開pad_char_to_full_length SQL 模式(SET sql_mode = "PAD_CHAR_TO_FULL_LENGTH";)

varchar類型:變長,精準,節省空間,存取速度慢

  字符長度範圍:0-65535(mysql行最大限制為65535字節)

  存儲:varchar類型存儲數據的真實內容,不會用空格填充;

     varchar類型會在真實數據前加1~2個bytes作為前綴,該前綴用來表示真實數據的bytes字節數(1~2bytes最大表示65535個數字,正好符合mysql對row的最大字節限制,即已經足夠使用)

     如果真實的數據<255則需要一個bytes的前綴(1Bytes=8bit 2**8最大表示的數字為255)

     如果真實的數據>255bytes則需要2Bytes的前綴(2Bytes=16bit 2**16最大表示的數字為65535)

  檢索: 尾部有空格會保存下來,在檢索或者說查詢時,也會正常顯示包含空格在內的內容

技術分享圖片

# length:查看字節數; char_length:查看字符數

1. char填充空格來滿足固定長度,但是在查詢時會自動刪除尾部的空格來匹配查詢值

2. 雖然char和varchar的存儲方式不太相同,但是對於兩個字符串的比較,都是只比較其值,忽略char存在的右填充,即使將sql_mode設置成PAD_CHAR_TO_FULL_LENGTH也一樣;但這不適用於like

所以,雖然varchar使用起來比較靈活,但是從整個系統的性能角度來說,char數據類型的處理速度更快

枚舉類型和集合類型:

字段的值只能在給定範圍內選擇,如單選框、多選框

enum 單選 只能在給定的範圍內選一個值,如性別 sex male/female

set 多選 在給定的範圍內可以選擇一個或多個值(愛好1,愛好2.。。)

create table client(name char(20),
                    age int,
                    sex enum("female","male"),
                    level enum("vip1","vip2","vip3"),
                    hobbies set("reading","working out","music","run")
                    );

insert client values("neo",18,"male","vip1","music,run"),
                    ("alex",73,"female","vip3","boy");

運行結果:

技術分享圖片

約束條件:

not null和default:

create table condition_null_default(
                                    id int,
                                    name char(10),
                                    sex enum("male","female") not null default "male"
                                    );

insert condition_null_default(id,name) values(1,"neo"),
                                             (2,"alina","female");

如下:

技術分享圖片

約束條件 unique key:

單列唯一:

方式一:

create table department1(
id int unique,
name char(10) unique
);

insert department1 values(1,"IT"),(2,"Sales);

方式二:

create table department2(
id int,
name char(10),
unique(id),
unique(name)
);

技術分享圖片

聯合唯一:

create table server(
id int unique,
ip char(15),
port int,
unique(ip,port)
);    # unique(ip,port)的含義是: ip和port拼到一起後必須是唯一的

技術分享圖片

primary key:

約束:not null unique(不為空且唯一)

存儲引擎(默認innodb):對於innodb存儲引擎來說,一張表內必須有一個主鍵(通常將id字段設為主鍵)

單列主鍵:

create table t_primary(
id int primary key,name char(16));

技術分享圖片

對於innodb,如果你不指定主鍵,innodb會找一個不為空且唯一的字段作為主鍵;如果沒找到,就用它自己隱藏的字段作為主鍵;如下

技術分享圖片

復合主鍵:

create table t_union_primary(
ip char(15),
port int,
primary key(ip,port)
);    # ip和port聯合組成主鍵

技術分享圖片

auto_increment: (自增長)

create table t_auto_incre(
id int primary key auto_increment,
name char(16));   # auto_increment的字段需要指定key  # 默認是從1開始,每次增加1

insert t_auto_incre(name) values("neo"),
("egon"),
("alex");

技術分享圖片

如果中間自己不按順序插入了id,後面的id auto_increment時以你新插入的id作為起點

insert t_auto_incre(id,name) values(7,"neo1");

insert t_auto_incre(name) values
("NEO1"),
("NEO2"),
("NEO3");

技術分享圖片

# 查看mysql關於auto_increment的默認設置
show variables like "auto_inc%";      # show variables 是查看變量,like是模糊匹配,%代表任意長度的任意字符

技術分享圖片

  # 步長: auto_increment_increment默認為1

  # 起始偏移量(位置): auto_increment_offset默認為1

#設置步長:
set session auto_increment_increment=5;
set global auto_increment_increment=5;

#session是會話級別的修改,就是只在本次運行時有效,退出再登錄後會恢復到原先的設置;
#global是全局級別的修改,長期有效,但需要推出後重新登錄mysql才會生效

#設置起始偏移量:
set session auto_increment_offset=3;
set global auto_increment_offset=3;
#用法同上;需要註意的一點:起始偏移量必須要小於等於步長

技術分享圖片

清空表:

  delete from 表名 where xxx; 不要用delete去清空表,delete用在跟where語句連用的情況下;delete from 表名 無法刪除自增長(auto_increment)的紀錄

  truncate 表名; 清空表應該用 truncate(能把自增長的紀錄也刪除掉)

foreign key(外鍵):建立表之間的關系

1. 建表

# 先建被關聯的表,並且保證保證被關聯的字段唯一
create table dept(
id int primary key,
name char(16),
comment char(50));

# 再建關聯表
create table emp(
id int primary key,
name char(10),
sex enum("male","female"),
dept_id int,
foreign key(dept_id) references dept(id));   # dept_id是外鍵,關聯到dept表的id字段

技術分享圖片

2. 插入數據

# 先往被關聯表中插入紀錄
insert dept values
(1,"IT","幹技術的"),
(2,"Sales","賣東西的"),
(3,"Finance","花錢的");

# 再往關聯表中插入數據
insert emp values
(1,"neo","male",1),
(2,"alex","female",2),
(3,"egon","male",3);   # 因為只有被關聯表的關聯字段建起來後關聯表才能去關聯;後有紀錄的那張表加foreign key

技術分享圖片

技術分享圖片

技術分享圖片

上述建表方式由於沒有指定 on delete cascade on update cascade,所以不能直接操作被關聯表

如果想刪除、更新同步(即 刪除、更細被關聯表的關聯字段,關聯表也自動跟著刪除、更新),關聯表建表時要加上 on delete cascase on update cascade 例如:foreign key(dept_id) references dept(id) on delete cascade on update cascade

# 建被關聯的表
create table dept(
id int primary key,
name char(16),
comment char(50));

# 建關聯表
create table emp(
id int primary key,
name char(10),
sex enum("male","female"),
dept_id int,
foreign key(dept_id) references dept(id) on delete cascade on update cascade
);     # 加上 on delete cascade on update cascade
delete from dept where id=1;
update dept set id=202 where id=2;

tips:實際項目中盡量不要把兩張表建立硬性限制(foreign key),最好能從邏輯上去實現兩張表的關系,即從應用程序代碼的層面上去實現兩張表的關系,不要再數據庫利用foreign key去建立硬性關系(這樣不利於擴展)

表與表之間的關系: 多對一、多對多、一對一

多對一:例如上面的例子,員工表emp中多個人紀錄可以對應部門表dept中的一個部門紀錄,但多個部門紀錄卻不能對應一個人(即 多個人可以在一個部門下,但一個人卻不能在多個部門),這就是多對一

多對多:A表中的多條紀錄可以對應B表中的一條紀錄,同時B表中的多條紀錄也可以對應A表中的一條紀錄,這就是多對多;多對多需要專門另外建一張表來存多對多之間的關系;例如下面的書與作者的例子:

create table author(
id int primary key auto_increment,
name char(16));

create table book(
id int primary key auto_increment,
name char(50));

# 專門建一張表來保存多對多那兩張表之間的關系
create table author2book(
id int not null unique auto_increment,
author_id int not null,
foreign key(author_id) references author(id)
on delete cascade
on update cascade,
book_id int not null,
foreign key(book_id) references book(id)
on delete cascade
on update cascade,
primary key(author_id,book_id));   # author_id去多對一author表中的id字段,book_id去多對一book表中的id字段

insert author(name) values("neo"),("egon"),("alex"),("wusir");
insert book(name) values("python自動化"),("linux運維"),("python全棧");

# 插入多對多之間的關系
insert author2book(author_id,book_id) values
(1,1),(1,2),(1,3),
(2,1),(2,2),
(3,2),
(4,2),(4,3);

一對一:兩張表中的紀錄最多只能互相對應中的一條紀錄,即一一對應,例如博客園中一個昵稱只能對應一個博客鏈接,一個博客鏈接也只能對應一個昵稱

以培訓機構的custome和student為例,客戶(customer)表中的一條紀錄最多只能對應student表中的一個紀錄,student表中的一條紀錄也一定對應customer表中的一條紀錄:

# 先有潛在客戶customer才能有學生(student),後有紀錄的那鐘表加foreign key
create table customer(
id int primary key auto_increment,
name char(10) not null,
phone int not null);

create table student(
id int primary key auto_increment,
class_name char(16) not null,
customer_id int unique,
foreign key(customer_id) references customer(id)
on delete cascade
on update cascade);   # 要想稱為一對一的表,student的字段 customer_id必須要指定為 unique; 外鍵一定要保證 unique !!!

insert into customer(name,phone) values
(李飛機,13811341220),
(王大炮,15213146809),
(守榴彈,1867141331),
(吳坦克,1851143312),
(贏火箭,1861243314),
(戰地雷,18811431230);

insert student(class_name,customer_id) values
("python周末5期",3),
("linux運維6期",5);

MySQL數據庫:SQL語句基礎、庫操作、表操作、數據類型、約束條件、表之間的關系