MySQL數據庫
非關系型數據庫的優勢:
-
性能
NOSQL是基于鍵值對的,可以想象成表中的主鍵和值的對應關系,而且不需要經過SQL層的解析,所以性能非常高。
-
可擴展性
同樣也是因為基于鍵值對,數據之間沒有耦合性,所以非常容易水平擴展。
關系型數據庫的優勢:
-
復雜查詢
可以用SQL語句方便的在一個表以及多個表之間做非常復雜的數據查詢。
-
事務支持
使得對于安全性能很高的數據訪問要求得以實現。
MySQL數據庫的介紹
發展史
1996年,MySQL 1.0
2008年1月16號 Sun公司收購MySQL。
2009年4月20,Oracle收購Sun公司。
MySQL是一種開放源代碼的關系型數據庫管理系統(RDBMS),使用最常用的數據庫管理語言--結構化查詢語言(SQL)進行數據庫管理。
MySQL是開放源代碼的,因此任何人都可以在General Public License的許可下下載并根據個性化的需要對其進行修改。
MySQL因為其速度、可靠性和適應性而備受關注。大多數人都認為在不需要事務化處理的情況下,MySQL是管理內容最好的選擇。
一 進入到MySQL數據庫
#正常的標準形式
mysql -h127.0.0.1 -uroot -p#-h HOST -u USER -p PASSWORD
#每個數據庫都有一個默認的root超級管理員
#默認沒有數據庫的密碼
#建議的使用方式
mysql -uroot -p
#如果訪問的是本機的數據庫 -h可以為 127.0.0.1/localhost/本機的ip地址
二 對于MySQL數據庫的操作
命令為:
? CREATE創建 DROP刪除 SHOW查看 ALTER修改庫或者表的結構
- 查看所有的數據庫
mysql> show databases;
-
選擇數據庫
use 庫名
-
查看當前所在的數據庫
select database()
-
查看當前庫下 所有的表
show tables()
-
創建數據庫
create database 庫名
-
查看創建庫的信息
show create database 庫名
-
創建一個不存在的數據庫 python 如果存在在不創建 不存在則創建 (不管在不在 都執行成功 防止報錯)
create database if not exists 庫名
-
刪除數據庫
drop database 庫名
-
刪除數據庫 防止報錯
drop database if exists 庫名
設置數據庫的字符集
alter database 庫名 character set utf8/latin1(之前數據庫默認latin1)
-
創建庫 并設置字符集 在該庫下創建的表和字段 默認都為 utf8字符編碼
create database 庫名 character set utf8
三 對數據庫的數據表進行操作
-
查看所有的表
show tables
-
刪除數據表
drop table if exists 表名
-
創建表
CREATE TABLE `user` ( #字段名 數據類型 `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(10) NOT NULL DEFAULT '帥哥', `sex` enum('w','m') DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8
-
對于表字段的刪除
alter table 表名 drop 字段名
-
給表 添加字段
alter table 表名 add 字段名..... after 字段名
MySQL必須知道的
- MySQL數據庫的命令 不區分大小寫
- 每創建一個數據庫 都會對應在當前MySQL數據庫下 創建 一個為你數據庫名字的文件夾 里面包含 該庫下面的所有的表
- 在Windows下 庫名也不區分大小寫 但是如果是在Linux 下 嚴格區分大小寫
- \G 以豎著形式進行查看
- \c 撤銷當前的命令
- 如果 出現引號沒有閉合的情況下 必須將另外的引號 補全 再次 \c 撤銷命令
- \q/quit/exit 對數據庫進行退出
MySQL開啟不嚴謹報錯
修改my.ini配置文件
路徑:C:\ProgramData\MySQL\MySQL Server 5.7
sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
latin1有的版本默認字符編碼
MySQL服務無法正常啟動的解決方法(1053錯誤)
是mysql權限問題,開始->輸入services.msc,找到MySQL服務,右鍵屬性,登錄,選擇此帳戶,然后選擇Administrator和相應密碼,確定。就能啟動了。
授權root可以通過外網IP進行訪問
GRANT ALL PRIVILEGES ON . TO 'root'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;
MySQL表的創建
一 字段類型
-
數值類型
類型 大小 范圍(有符號) 范圍(無符號) 用途 TINYINT 1 字節 (-128,127) (0,255) 小整數值 SMALLINT 2 字節 (-32 768,32 767) (0,65 535) 大整數值 INT或INTEGER 4 字節 (-2 147 483 648,2 147 483 647) (0,4 294 967 295) 大整數值 FLOAT 4 字節 單精度浮點數值 DOUBLE 8 字節 雙精度浮點數值 DECIMAL[?d?s?m?l] Gld對DECIMAL(M,D) ,如果M>D,為M+2否則為D+2 依賴于M和D的值 依賴于M和D的值 小數值(更加準確) -
–INT(3)、SMALLINT(3)等整型后面的數字不會影響數值的存儲范圍,只會影響顯示
–整型后面的數字只有配合零填充的時候才有實際意義。 zerofill
–整型后面的數字可以省略
Decimal 小數類型不僅能夠保證數據計算更為精確,還可以節省儲存空間
Float/double/decimal 在存儲的時候 小數點超出的時候 會4舍五入
-
-
日期和時間類型
類型 大小(字節) 范圍 格式 用途 DATE 3 1000-01-01/9999-12-31 YYYY-MM-DD 日期值 TIME 3 '-838:59:59'/'838:59:59' HH:MM:SS 時間值或持續時間 YEAR 1 1901/2155 YYYY 年份值 DATETIME 8 1000-01-01 00:00:00/9999-12-31 23:59:59 YYYY-MM-DD HH:MM:SS 混合日期和時間值 TIMESTAMP 4 1970-01-01 00:00:00/2038 結束時間是第 2147483647 秒,北京時間 2038-1-19 11:14:07,格林尼治時間 2038年1月19日 凌晨 03:14:07 YYYYMMDD HHMMSS 混合日期和時間值,時間戳 日期類型注意事項:
–存儲日期時,我們可以使用整型來進行存儲時間戳,這樣做便于我們進行日期的計算
-
字符串類型
類型 大小 用途 CHAR 0-255字節 定長字符串 VARCHAR 0-65535 字節 變長字符串 TINYBLOB 0-255字節 不超過 255 個字符的二進制字符串 TINYTEXT 0-255字節 短文本字符串 BLOB 0-65 535字節 二進制形式的長文本數據 TEXT 0-65 535字節 長文本數據 MEDIUMBLOB 0-16 777 215字節 二進制形式的中等長度文本數據 MEDIUMTEXT 0-16 777 215字節 中等長度文本數據 LONGBLOB 0-4 294 967 295字節 二進制形式的極大文本數據 LONGTEXT 0-4 294 967 295字節 極大文本數據 enum(“w”,"m") 65535個成員 枚舉:可賦予某個枚舉成員mc set(“w”,"m") 64個成員 集合:可賦予多個集合成員 多個值用逗號隔開 字符串類型注意事項:
-
Char varchar區別:char執行效率 高于 varchar varchar 相對于char節省空間
- –CHAR和VARCHAR類型的長度范圍都在0~255之間
-
Char varchar區別:char執行效率 高于 varchar varchar 相對于char節省空間
+ –在使用CHAR和VARCHAR類型時,當我們傳入的實際的值的長度大于指定的長度,字符串會被截取至指定長度
+ –在使用CHAR類型時,如果我們傳入的值的長度小于指定長度,實際長度會使用空格補至指定長度
+ –在使用VARCHAR類型時,如果我們傳入的值的長度小于指定長度,實際長度即為傳入字符串的長度,不會使用空格填補
+ –CHAR要比VARCHAR效率更高,但占用空間較大
-
–BLOB和TEXT類型是可以存放任意大數據的數據類型
–BLOB區分大小寫,TEXT不區分大小寫
–ENUM和SET類型是特殊的的串類型,其列值必須從固定的串集中選擇
–ENUM只能選擇其中一個值,SET可以選擇多個值
?
三 字段約束
-
unsigned 無符號 正數
只能用于設置數值類型,不允許出現負數
最大存儲長度會增加一倍
-
zerofill 零填充
只能用于設置數值類型,在數值之前會自動用0補齊不足的位數
-
auto_increment 自增
用于設置字段的自動增長屬性,每增加一條記錄,該字段的值會自動加1
-
default 默認值
可以通過此屬性來指定一個默認值,如果沒有在此列添加值,那么默認添加此值
在修改表的某字段的時候 再次添加默認值的時候 只有在添加新的值的時候才會出現默認值 否則只有添加新的字段的時候 默認值才會將沒有值的填充上 null也是值 空值
-
Null和not null
默認為NULL,即插入值時沒有在此字段插入值,默認為NULL值,如果指定了NOT NULL,則必須在插入值時在此字段填入值
-
comment 設置當前字段的說明
實例
create table b( -> age tinyint unsigned comment '年齡' -> ) engine=innodb default charset=utf8 comment='b表' -> ;n
給字段加注釋
alter table 表名 modify 字段名 類型 約束條件 comment='注釋內容'
給表添加注釋
alter table 表名 comment='注釋內容'
NULL值注意事項:
-NULL意味著“沒有值”或“未知值”
–可以測試某個值是否為NULL
–不能對NULL值進行算術計算
–對NULL值進行算術運算,其結果還是NULL
–0或NULL都意味著假,其余值都意味著真
四 在MySQL中,主要有四類索引:
主鍵索引(PRIMARY KEY)
唯一索引(UNIQUE)
常規索引(INDEX)
全文索引(FULLTEXT)
(1) 主鍵索引
主鍵索引是關系數據庫中最常見的索引類型,主要作用是確定數據表里一條特定的數據記錄的位置。我們可以在字段后添加PRIMARY KEY來對字段設置為主鍵索引。
注意:
1.最好為每張表指定一個主鍵,但不是必須指定。
2.一個表只能指定一個主鍵,而且主鍵的值不能為空
3.主鍵可以有多個候選索引(例如NOT NULL,AUTO_INCREMENT)
自增的步長:
mysql是的默認步長是基于會話session的 查看全局變量,其中默認是1
mysql> show session variables like 'auto_inc%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| auto_increment_increment | 1 |
| auto_increment_offset | 1 |
+--------------------------+-------+
2 rows in set (0.00 sec)
設置步長基于會話步長,只能自該自己的會話
set session auto_increment_increment=2; 設置會話步長
set session auto_increment_offset=10; 設置開始的位置
基于全局的級別的,可以修改全部的會話
show global variables like 'auto_inc%'; 查看全局變量
set global auto_increment_increment=2; 設置會話步長
set global auto_increment_offset=10;
修改表的自增的值
alter table 表名 auto_increment = 1 #再次從1 開始遞增
(2) 唯一索引
唯一索引與主鍵索引一樣,都可以防止創建重復的值。但是,不同之處在于,每個數據表中只能有一個主鍵索引,但可以有多個唯一索引。我們使用關鍵字UNIQUE對字段定義為唯一索引
(3) 常規索引
常規索引技術是關系數據查詢中最重要的技術,如果要升數據庫的性能,索引優化是首先應該考慮的,因為它能使我們的數據庫得到最大性能方面的提升。常規索引也存在缺點:
1.多占用磁盤空間
2.會減慢插入,刪除和修改操作
3.需要按照索引列上排序格式執行
創建索引我們可以使用INDEX和KEY關鍵字隨表一同創建。
(4) 全文索引
alter table user add fulltext a(article)
全文索引在MySQL中是一個FULLTEXT類型索引,但FULLTEXT索引只能用于MyISAM表,并且只可以在CHAR、VARCHAR或TEXT類型的列上創建,也允許創建在一個或多個數據列上。
但是FULLTEXT是不支持中文全文索引的,所以我們將來會使用效率更高的全文索引引擎Sphinx。
五 數據表的類型及存儲位置
MyISAM和InnoDB兩種表類型最為重要:
1.MyISAM數據表類型的特點是成熟、穩定和易于管理。
2.MyISAM表類型會產生碎片空間,要經常使用OPTIMIZE TABLE命令去清理表空間
3.MyISAM不支持事務處理,InnoDB支持
4.MyISAM不支持外鍵,InnoDB支持
5.MyISAM表類型的數據表效率更
6.MyISAM表類型的數據表會產生三個文件,InnoDB表類型表默認只會產生一個文件。
六 不同表引擎存儲的區別
.frm文件:存儲數據表的框架結構,文件名與表名相同,每個表對應一個同名frm文件,
1、MyISAM數據庫表文件:
.MYD文件:即MY Data,表數據文件
.MYI文件:即MY Index,索引文件
.log文件:日志文件
3、InnoDB采用表空間(tablespace)來管理數據,存儲表數據和索引
InnoDB數據庫文件(即InnoDB文件集,ib-file set):
sibdata1、ibdata2等:系統表空間文件,存儲InnoDmB系統信息和用戶數據庫表數據和索引,所有表共用
.ibd文件:單表表空間文件,每個表使用一個表空間文件(file per table),存放用戶數據庫表數據和索引
日志文件: ib_logfile1、ib_logfile2
六 innodb的事務處理
數據庫默認類型為mysiam類型
engine = INNODB
命令修改表類型
alter table 表名 engine=innodb;
(1) 查詢當前是否為 自動提交
Select @@autocommit 值為1 為自動提交
(2) 開啟事務處理
set autocommit = 0;
(3) 事務開始
begin;
(4) 執行sql語句
insert into 。。。。
(5) 提交或者回滾
commit work 提交
rollback work 回滾
注意:
- 如果開啟了事務處理 在對數據進行了操作 但是沒有執行 commit的時候 退出數據庫 那么對數據進行操作的都不會保存
- 只有innodb才支持事務處理
七 建表的注意事項
1.表的字段之間要使用逗號隔開。
2.建表的最后一句一定不能有逗號。
3.表名稱和字段名稱盡量不要使用MySQL系統的關鍵字
4.如果一定要使用關鍵字,我們可以使用反引號將表名稱和字段名稱包含起來來進行過濾屏蔽。
5.使用反引號會使建表效率增高。
6.數據表名稱和字段名稱不能重名
7.AUTO_INCREMENT屬性必須依附于主鍵索引
二 對表結構的操作
-
給表添加一個新的字段
alter table 表名 add 字段名 類型 約束條件
-
給表 刪除一個字段
alter table 表名 drop 字段名
-
更改字段名
alter table 表名 change 原字段名 新字段名 類型 約束條件
-
修改字段信息
alter table 表名 modify 字段名 字段類型 約束條件
-
表添加索引
alter table 表名 add 索引類型 索引名(字段名) #添加索引名的索引
alter table 表名 add 索引類型(字段名) #不添加索引名的索引 默認索引名為字段名
-
刪除索引
alter table 表名 drop key 索引名
-
創建一個 和 a表一樣的表 b
create table b like a
-
查看表的所有索引
show index from 表名
-
修改表的字符編碼
alter table aa character set utf8;
-
修改表的某個字段的字符編碼
alter table aa modify name varchar(20) character set utf8;
八 INSERT 數據的添加
-
指定字段添加值
insert into 表名(字段名,,) values(值,)
-
不指定字段 添加值
insert into 表名 values(值)
注意:
? 所有字段都需要一一對應的添加上值
-
指定字段添加多個值
insert into user(字段名) values(值一),(值二)
-
不指定字段添加多個值
insert into user values(值一),(值二)
九 SELECT 數據的查詢
-
不指定字段的查詢 (不建議)
select * from 表名
-
指定字段的數據查詢(建議)
select 字段名,,,, from 表名
-
對查詢的字段 起別名
select 字段名 as 別名 from 表名
十 WHERE 條件
(1) 比較運算符
-
>
select * from 表名 where age>181
-
<
select * from 表名 where age<18
-
>=
select * from 表名 where age>=18
-
<=
select * from 表名 where age<=18
-
!=/<>
select * from 表名 where age!=18
select * from 表名 where age<>18
=
(2) 邏輯運算符
-
and 并且
select age from 表名 where age>10 and age<20
-
or 或運算
select age from 表名 where age>10 or age<20
-
between and 在什么范圍之內
select * from user where age between 10 and 20
select * from user where age>=10 and age<=22
-
not between and 不在什么范圍之內
select * from user where age not between 10 and 22
select * from user where age<10 or age>22
-
in 在,,,里面/not in 在,,,里面
select * from user where age in(16,27,38,22) #查詢所有信息 條件是 年齡在 16,27,38,22的年齡里
(3) 子查詢 sql語句的條件 還是sql語句
? select * from user where age in(select age from user where age between 10 and 20)
(4) 排序查詢 order by
-
默認為升序
order by age
order by age asc
-
降序排列
order by 字段名 desc
(5) is is not
-
查詢 age為null的數據
select * from user where age is null
-
查詢age不為null的數據
select * from user where age is not null
(6) limit x,y 從x開始 取y條數據 如果從0取y條數據 那么x可以省略
? select * from user limit 0,5
? 組合體:
? select * from user where age>10 and age <22 and phone is not null order by age desc limit 2
? 查詢所有的信息 條件是 年齡在10到22之間 并且 電話不為 空 取兩條年齡最大的數據
刪除表所有的數據
- delete from 表名
- truncate 表名
區別:
? delete 刪除表所有的數據 再次添加數據的時候 主鍵自增 會在原有的基礎上 繼續自增
? truncate 會將cpszs 主鍵自增歸位 也就是 再次添加數據 從1開始遞增
修改表的自增的值
alter table 表名 auto_increment = 1 #再次從1 開始遞增
group by 分組
select sex,count(*) from user group by sex #按照性別分組 并統計有多少人
select class,count(*) as person from user group by class; #統計 每個班級 有多少人
select class,sex,count(*) as person from user group by class,sex; #統計每個班的男生和女生分別有多少人
having 相當于 where
select class,sex,count(*) as person from user group by class,sex having person>10; #查詢 人數 在10個以上的男生或女生
select class,count(*) as person from user group by class having person>50; #查詢50人 以上的班級
select classid,sex,count(*) p from a group by classid,sex having classid in('python1708','python1707') and p>2;
select classid,count(*) as t from a group by classid having classid in('python1706','python1707') and t>1; #統計classid為 1706或者1707 的 人數大于1人的p
like 模糊查詢
'%字符%' 包含某個字符
‘字符%’ 以什么字符作為開頭
'%字符' 以什么字符作為 結尾
select * from 表名 where 字段 like ‘%字符%’ #查詢 某個字段中 包含 某個字符的所有數據
select name,age from user where name like '%王%' order by age desc limit 0,5; #查詢 姓名包含王字的年齡最大的5條數據
select * from user where name like '%王%'and age>18 order by id desc limit 5; #查詢 姓名包含王字的姓名 并且年齡大于18 降序排列 取5條數據
DELETE 刪除 (如果沒有where 默認刪除所有數據)
delete from 表名 where 條件
UPDATE 修改(如果沒有條件 默認修改所有的數據)
update 表名 set 字段名=字段值,,, where 條件
DISTINCT 去除重復數據
select distinct 字段名 from 表名
select age from user group by age #查詢去除重復數據的年齡
多表聯查
(1) 隱式內鏈接
? select * from 表1,表2 where 表1.字段名 = 表2.字段名
? select u.id,u.name,info.email,info.address from user u,userinfo info where u.id=info.uid 查詢倆個表里的某些字段
(2) 顯式內鏈接
? select * from 表1 inner join 表2 on 表1.字段名 = 表2.字段名
?
(3) left join 左鏈接
? select * from userinfo u LEFT JOIN user info on u.uid=info.id
注意:
? 以左表位主表 右表為輔表 會把主表的數據全部查出來 輔表的數據有對應的就查出來 沒有 就以null來補全
(4) right join 右鏈接
? select * from userinfo u right JOIN user info on u.uid=info.id
? 注意:
? 以右表位主表 左表為輔表 會把主表的數據全部查出來 輔表的數據有對應的就查出來 沒有 就以null來補全
MySQL的聚合函數
- count() 統計個數
- max() 最大的
- min() 最小的
- sum() 求和
- avg() 求平均數
數據庫的導入導出
(1)導入
? mysql -uroot -p 庫名<demo.sql
(2)導出
? mysqldump -uroot -p 庫名>demo.sql
以下作為了解
修改密碼
方法1 用SET PASSWORD命令
set password for 用戶名@loclhost = passworsd('新密碼');
方法2 用UPDATE直接編輯user表
- 首先登錄MySQL。
- 連接權限數據庫: use mysql; 。
- 改密碼:update user set password=password("shapolang") where user="root";(別忘了最后加分號)
- 刷新權限(必須步驟):flush privileges;
重新登錄,輸入新密碼shapolang就ok了;
(1) 使用 mysql庫
? use mysql
(2) 查看當前數據庫下有 哪些用戶
? select user from user
(3)創建用戶
? create user lisi identified by '123456';
(4) 修改用戶名
? rename user lisi to wangwu;
(5) 賦予權限
? grant all on demo.* to wangwu;
? all 所有的權限
? select,update 賦予 查 和改的權限
(6) 回收權限
? revoke all on demo.* from wangwu;
(7) 刪除用戶
? drop user wangwu
(8) 刷新
? flush privileges
無限極分類
select * from type order by concat(path,id); #concat 將字段 鏈接在一起
id | pid | typename | path |
---|---|---|---|
1 | 0 | movie | 0, |
2 | 1 | japanmovie | 0,1, |
3 | 1 | 美國movie | 0,1, |
7 | 1 | Chinesemovie | 0,1 |
4 | 0 | 衣服 | 0, |
5 | 4 | 內衣 | 0,4, |
6 | 5 | 紅豆 | 0,4,5, |
一 Python 操作 MySQL
import pymysql
pip install pymysql
(1) 連接MySQL數據庫
? db = pymysql.connect(主機名,用戶名,密碼,數據庫名)
(2) 設置字符集
? db.set_charset(‘utf8’)
? cursor = db.cursor()
(4) 執行sql語句
? cursor.execute(sql語句)
(5) 獲取所有的結果集
? cursor.fetchall()
(6) 獲取一條數據
? cursor.fetchone()
(7) 獲取當前sql語句 所受影響的行數
? cursor.rowcount
(8) 關閉數據庫鏈接
? db.close()
拼湊正常完整的sql語句
print("select name,password from user where name=\""+username+"\"")
print("select name,password from user where name='"+username+"'")
print("select name,password from user where name='%s'"%(username))
print("select name,password from user where name='{}'".format(username))
二 執行事務
事務機制可以確保數據一致性。
事務應該具有4個屬性:原子性、一致性、隔離性、持久性。這四個屬性通常稱為ACID特性。
- 原子性(atomicity)。一個事務是一個不可分割的工作單位,事務中包括的諸操作要么都做,要么都不做。
- 一致性(consistency)。事務必須是使數據庫從一個一致性狀態變到另一個一致性狀態。一致性與原子性是密切相關的。
- 隔離性(isolation)。一個事務的執行不能被其他事務干擾。即一個事務內部的操作及使用的數據對并發的其他事務是隔離的,并發執行的各個事務之間不能互相干擾。
- 持久性(durability)。持續性也稱永久性(permanence),指一個事務一旦提交,它對數據庫中數據的改變就應該是永久性的。接下來的其他操作或故障不應該對其有任何影響。
Python DB API 2.0 的事務提供了兩個方法 commit 或 rollback。
實例
實例(Python 3.0+)
# SQL刪除記錄語句
sql = "DELETE FROM EMPLOYEE WHERE AGE > '%d'" % (20)
try:
# 執行SQL語句
cursor.execute(sql)
# 向數據庫提交
db.commit()
except:
# 發生錯誤時回滾
db.rollback()
對于支持事務的數據庫, 在Python數據庫編程中,當游標建立之時,就自動開始了一個隱形的數據庫事務。
commit()方法游標的所有更新操作,rollback()方法回滾當前游標的所有操作。每一個方法都開始了一個新的事務。
三 Python的hashlib提供了常見的摘要算法,如MD5,SHA1等等。
md5講數據加密成32位長度的字符串
import hashlib
# 計算出一個字符串的MD5值:
md5 = hashlib.md5() #MD5加密
md5.update('how to use md5 in python hashlib?'.encode('utf-8'))
print(md5.hexdigest())