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


數據庫相關概念:

  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(10));  (創建文件(表),文件名是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)
   alter table t1 alter column name set default "NEO"; -- 修改默認值
刪:
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)構造

  int[(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);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM