安裝MySQLdbhtml
MySQLdb 是用於Python連接Mysql數據庫的接口,若是是windows系統:登陸https://pypi.python.org/pypi/MySQL-python/1.2.5找到.exe結尾的包,直接安裝便可python
如下界面即表明成功安裝mysql
若是是linux或者其餘系統,能夠下載源碼包進行安裝:上節連接中的zip包,而後安裝:linux
yum install –y python-devel yum install –y mysql-devel yum install –y gcc unzip MySQL-python-1.2.5.zip cd MySQL-python-1.2.5 python setup.py build python setup.py install
數據庫鏈接
MySQLdb提供了connect方法用來和數據庫創建鏈接,接收數個參數,返回鏈接對象:
代碼以下:
首先在mysql的數據庫中創建python庫:create database python;
conn=MySQLdb.connect(host="192.168.48.128",user="xiang",passwd="123456",db="python",charset="utf8")
比較經常使用的參數包括:
host:數據庫主機名.默認是用本地主機
user:數據庫登錄名.默認是當前用戶
passwd:數據庫登錄的祕密.默認爲空
db:要使用的數據庫名.沒有默認值
port:MySQL服務使用的TCP端口.默認是3306,數字類型
charset:數據庫編碼
更多關於參數的信息能夠查這裏 http://mysql-python.sourceforge.net/MySQLdb.html
有時候,爲了咱們代碼的規範,我更加推薦把全部數據庫的配置寫在一個字典中sql
import MySQLdb #鏈接數據庫 # host 數據庫ip # port 數據庫端口 # user 鏈接數據庫用戶 # passwd 用戶密碼 # db 數據庫名字 # charset 字符集 utf-8 import MySQLdb conn=MySQLdb.connect(host="192.168.214.26",user="bigk",passwd="123456",db="bigk",charset="utf8") def connect_mysql(): db_config={ "host":"192.168.214.26", "port":3306, "user":"bigk", "passwd":"123456", "db":"bigk", "charset":"utf8" } cnx=MySQLdb.connect(**db_config) return cnx print(connect_mysql())
Mysql事務
在講遊標以前,咱們先來了解什麼是mysql的事物。這對遊標的理解很是有幫助。
mysql事務
MySQL 事務主要用於處理操做量大,複雜度高的數據。好比,你操做一個數據庫,公司的一個員工離職了,你要在數據庫中刪除他的資料,也要刪除該人員相關的,好比郵箱,我的資產等。這些數據庫操做語言就構成了一個事務。
在MySQL中只有使用了Innodb數據庫引擎的數據庫或表才支持事務,因此不少狀況下咱們都使用innodb引擎。
事務處理能夠用來維護數據庫的完整性,保證成批的SQL語句要麼所有執行,要麼所有不執行。
通常來講,事務是必須知足4個條件(ACID): Atomicity(原子性)、Consistency(穩定性)、Isolation(隔離性)、Durability(可靠性)
一、事務的原子性:一組事務,要麼成功;要麼撤回。
二、穩定性 : 有非法數據(外鍵約束之類),事務撤回。
三、隔離性:事務獨立運行。一個事務處理後的結果,影響了其餘事務,那麼其餘事務會撤回。事務的100%隔離,須要犧牲速度。
四、可靠性:軟、硬件崩潰後,InnoDB數據表驅動會利用日誌文件重構修改。可靠性和高速度不可兼得, innodb_flush_log_at_trx_commit選項 決定何時吧事務保存到日誌裏。
而mysql在默認的狀況下,他是把每一個select,insert,update,delete等作爲一個事務的,登陸mysql服務器,進入mysql,執行如下命令:
mysql> show variables like 'auto%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| auto_increment_increment | 1 |
| auto_increment_offset | 1 |
| autocommit | ON |
| automatic_sp_privileges | ON |
+--------------------------+-------+
4 rows in set (0.00 sec)
如上所示: 有一個參數autocommit就是自動提交的意思,每執行一個msyql的select,insert,update等操做,就會進行自動提交。
若是把改選項關閉,咱們就能夠每次執行完一次代碼就須要進行手動提交,connect對象給咱們提供了兩種辦法來操做提交數據。
mysql事務的方法
commit():提交當前事務,若是是支持事務的數據庫執行增刪改後沒有commit則數據庫默認回滾,至關於刪除了以前的操做。默認自動開啓了autocommit功能
rollback():取消當前事務數據庫
import MySQLdb def connect_mysql(): db_config = { 'host': '192.168.214.26', 'port': 3306, 'user': 'bigk', 'passwd': '123456', 'db': 'bigk', 'charset': 'utf8' } cnx = MySQLdb.connect(**db_config) return cnx if __name__ == '__main__': cnx = connect_mysql() cus = cnx.cursor() sql = "create table test(id int not null);insert into test(id) values (100);" try: cus.execute(sql) cus.close() cnx.commit() except Exception as e: # cnx.rollback() # print('Error') raise e finally: cnx.close()
表結構設計windows
import MySQLdb def connect_mysql(): db_config = { 'host': '192.168.214.26', 'port': 3306, 'user': 'bigk', 'passwd': '123456', 'db': 'bigk', 'charset': 'utf8' } cnx = MySQLdb.connect(**db_config) return cnx if __name__ == '__main__': cnx = connect_mysql() cus = cnx.cursor() # sql = "create table test(id int not null);insert into test(id) values (100);" # student = ''' # create table student( # StdID int not null primary key. # StdNAME varchar(100) not null, # Gender enum('M','F'), # age tinyint # ); # ''' student = '''create table student( StdID int not null primary key auto_increment, StdName varchar(100) not null, Gender enum('M', 'F'), Age tinyint )''' course = '''create table Course( CouID int not null, CName varchar(50) not null, TID int not null )''' score = '''create table Score( SID int not null, StdID int not null, CID int not null, Grade int not null )''' teacher = '''create table Teacher( TID int not null, TName varchar(100) not null )''' tmp = '''set @i := 0; create table tmp as select (@i := @i + 1) as id from information_schema.tables limit 10; ''' try: cus.execute(student) cus.execute(course) cus.execute(score) cus.execute(teacher) cus.execute(tmp) cus.close() cnx.commit() # try: # cus.execute(student) # cus.close() # cnx.commit() except Exception as e: cnx.rollback() # print('Error') raise e finally: cnx.close()
建立表服務器
import MySQLdb def connect_mysql(): db_config = { 'host': '192.168.214.26', 'port': 3306, 'user': 'bigk', 'passwd': '123456', 'db': 'bigk', 'charset': 'utf8' } cnx = MySQLdb.connect(**db_config) return cnx if __name__ == '__main__': cnx = connect_mysql() cus = cnx.cursor() # sql = "create table test(id int not null);insert into test(id) values (100);" # student = ''' # create table student( # StdID int not null primary key. # StdNAME varchar(100) not null, # Gender enum('M','F'), # age tinyint # ); # ''' student = '''create table student( StdID int not null primary key auto_increment, StdName varchar(100) not null, Gender enum('M', 'F'), Age tinyint )''' course = '''create table Course( CouID int not null, CName varchar(50) not null, TID int not null )''' score = '''create table Score( SID int not null, StdID int not null, CID int not null, Grade int not null )''' teacher = '''create table Teacher( TID int not null, TName varchar(100) not null )''' tmp = '''set @i := 0; create table tmp as select (@i := @i + 1) as id from information_schema.tables limit 10; ''' try: cus.execute(student) cus.execute(course) cus.execute(score) cus.execute(teacher) cus.execute(tmp) cus.close() cnx.commit() # try: # cus.execute(student) # cus.close() # cnx.commit() except Exception as e: cnx.rollback() # print('Error') raise e finally: cnx.close()
增長數據ide
import MySQLdb def connect_mysql(): db_config = { 'host': '192.168.214.26', 'port': 3306, 'user': 'bigk', 'passwd': '123456', 'db': 'bigk', 'charset': 'utf8' } cnx = MySQLdb.connect(**db_config) return cnx if __name__ == '__main__': cnx = connect_mysql() students = '''set @i := 10000; insert into Student select @i:=@i+1, substr(concat(sha1(rand()), sha1(rand())), 1, 3 + floor(rand() * 75)), case floor(rand()*10) mod 2 when 1 then 'M' else 'F' end, 25-floor(rand() * 5) from tmp a, tmp b, tmp c, tmp d; ''' course = '''set @i := 10; insert into Course select @i:=@i+1, substr(concat(sha1(rand()), sha1(rand())), 1, 5 + floor(rand() * 40)), 1 + floor(rand() * 100) from tmp a; ''' score = '''set @i := 10000; insert into Score select @i := @i +1, floor(10001 + rand()*10000), floor(11 + rand()*10), floor(1+rand()*100) from tmp a, tmp b, tmp c, tmp d; ''' theacher = '''set @i := 100; insert into Teacher select @i:=@i+1, substr(concat(sha1(rand()), sha1(rand())), 1, 5 + floor(rand() * 80)) from tmp a, tmp b; ''' try: cus_students = cnx.cursor() cus_students.execute(students) cus_students.close() cus_course = cnx.cursor() cus_course.execute(course) cus_course.close() cus_score = cnx.cursor() cus_score.execute(score) cus_score.close() cus_teacher = cnx.cursor() cus_teacher.execute(theacher) cus_teacher.close() cnx.commit() except Exception as e: cnx.rollback() print('error') raise e finally: cnx.close()
查詢數據fetch
import MySQLdb def connect_mysql(): db_config = { 'host': '192.168.214.26', 'port': 3306, 'user': 'bigk', 'passwd': '123456', 'db': 'bigk', 'charset': 'utf8' } cnx = MySQLdb.connect(**db_config) return cnx if __name__ == '__main__': cnx = connect_mysql() sql = '''select * from Student where StdName in (select StdName from Student group by StdName having count(1)>1 ) order by StdName;''' try: cus = cnx.cursor() cus.execute(sql) result = cus.fetchall() with codecs.open('select.txt', 'w+') as f: for line in result: f.write(str(line)) f.write('\n') cus.close() cnx.commit() except Exception as e: cnx.rollback() print('error') raise e finally: cnx.close()
刪除數據
import MySQLdb def connect_mysql(): db_config = { 'host': '192.168.214.26', 'port': 3306, 'user': 'bigk', 'passwd': '123456', 'db': 'bigk', 'charset': 'utf8' } cnx = MySQLdb.connect(**db_config) return cnx if __name__ == '__main__': cnx = connect_mysql() sql = '''delete from Teacher where TID in( select TID from (select Course.CouID, Course.TID, Teacher.TName, count(Teacher.TID) as count_teacher from Course left join Score on Score.Grade < 60 and Course.CouID = Score.CouID left join Teacher on Course.TID = Teacher.TID group by Course.TID order by count_teacher desc limit 5) as test ) ''' try: cus = cnx.cursor() cus.execute(sql) result = cus.fetchall() cus.close() cnx.commit() except Exception as e: cnx.rollback() print('error') raise e finally: cnx.close()
更新數據
import MySQLdb def connect_mysql(): db_config = { 'host': '192.168.214.26', 'port': 3306, 'user': 'bigk', 'passwd': '123456', 'db': 'bigk', 'charset': 'utf8' } cnx = MySQLdb.connect(**db_config) return cnx if __name__ == '__main__': cnx = connect_mysql() sql = '''select *, (grade+60) as newGrade from Score where Grade <5;''' update = '''update Score set grade = grade + 60 where grade < 5; ''' try: cus_start = cnx.cursor() cus_start.execute(sql) result1 = cus_start.fetchall() print(len(result1)) cus_start.close() cus_update = cnx.cursor() cus_update.execute(update) cus_update.close() cus_end = cnx.cursor() cus_end.execute(sql) result2 = cus_end.fetchall() print(len(result2)) cus_end.close() cnx.commit() except Exception as e: cnx.rollback() print('error') raise e finally: cnx.close()
MySQL索引的概念
索引是一種特殊的文件(InnoDB數據表上的索引是表空間的一個組成部分),它們包含着對數據表裏全部記錄的引用指針。更通俗的說,數據庫索引比如是一本書前面的目錄,能加快數據庫的查詢速度。
索引類別
1.普通索引
普通索引(由關鍵字 KEY 或 INDEX 定義的索引)的惟一任務是加快對數據的訪問速度。所以,應該只爲那些最常常出如今查詢條件(WHERE column =)或排序條件(ORDER BY column)中的數據列建立索引。只要有可能,就應該選擇一個數據最整齊、最緊湊的數據列(如一個整數類型的數據列)來建立索引。
2.惟一索引
普通索引容許被索引的數據列包含重複的值。好比說,由於人有可能同名,因此同一個姓名在同一個「員工我的資料」數據表裏可能出現兩次或更屢次。
若是能肯定某個數據列將只包含彼此各不相同的值,在爲這個數據列建立索引的時候就應該用關鍵字UNIQUE 把它定義爲一個惟一索引。這麼作的好處:一是簡化了 MySQL 對這個索引的管理工做,這個索引也所以而變得更有效率;二是 MySQL 會在有新記錄插入數據表時,自動檢查新記錄的這個字段的值是否已經在某個記錄的這個字段裏出現過了;若是是,MySQL 將拒絕插入那條新記錄。也就是說,惟一索引能夠保證數據記錄的惟一性。事實上,在許多場合,人們建立惟一索引的目的每每不是爲了提升訪問速度,而只是爲了不數據出現重複。
3.主索引
在前面已經反覆屢次強調過:必須爲主鍵字段建立一個索引,這個索引就是所謂的「主索引」。主索引與惟一索引的惟一區別是:前者在定義時使用的關鍵字是 PRIMARY 而不是 UNIQUE。
4.外鍵索引
若是爲某個外鍵字段定義了一個外鍵約束條件,MySQL 就會定義一個內部索引來幫助本身以最有效率的方式去管理和使用外鍵約束條件。
5.複合索引
索引能夠覆蓋多個數據列,如像 INDEX (columnA, columnB) 索引。這種索引的特色是 MySQL 能夠有選擇地使用一個這樣的索引。若是查詢操做只須要用到 columnA 數據列上的一個索引,就可使用複合索引 INDEX(columnA, columnB)。不過,這種用法僅適用於在複合索引中排列在前的數據列組合。好比說,INDEX (A,B,C) 能夠當作 A 或 (A,B) 的索引來使用,但不能當作 B、C 或 (B,C) 的索引來使用。
import MySQLdb def connect_mysql(): db_config = { 'host': '192.168.214.26', 'port': 3306, 'user': 'bigk', 'passwd': '123456', 'db': 'bigk', 'charset': 'utf8' } cnx = MySQLdb.connect(**db_config) return cnx if __name__ == '__main__': cnx = connect_mysql() sql1 = '''alter table Teacher add primary key(TID);''' sql2 = '''alter table Student add primary key(StdID);''' sql3 = '''alter table Score add primary key(SID);''' sql4 = '''alter table Course add primary key(CouID);''' sql5 = '''alter table Score add index idx_StdID_CouID(StdID, CouID);''' # sql6 = '''alter table Score drop index idx_StdID_CouID;''' 刪除索引 sql7 = '''explain select * from Score where StdID = 16213;''' try: cus = cnx.cursor() cus.execute(sql1) cus.close() cus = cnx.cursor() cus.execute(sql2) cus.close() cus = cnx.cursor() cus.execute(sql3) cus.close() cus = cnx.cursor() cus.execute(sql4) cus.close() cus = cnx.cursor() cus.execute(sql5) cus.close() cus = cnx.cursor() cus.execute(sql7) result = cus.fetchall() print(result) cus.close() cnx.commit() except Exception as e: cnx.rollback() print('error') raise e finally: cnx.close()
主鍵和索引的區別
1. 主鍵必定是惟一性索引,惟一性索引並不必定就是主鍵。 所謂主鍵就是可以惟一標識表中某一行的屬性或屬性組,一個表只能有一個主鍵,但能夠有多個候選索引。由於主鍵能夠惟一標識某一行記錄,因此能夠確保執行數據更新、刪除的時候不會出現張冠李戴的錯誤。主鍵除了上述做用外,經常與外鍵構成參照完整性約束,防止出現數據不一致。數據庫在設計時,主鍵起到了很重要的做用。 主鍵能夠保證記錄的惟一和主鍵域非空,數據庫管理系統對於主鍵自動生成惟一索引,因此主鍵也是一個特殊的索引。 2. 一個表中能夠有多個惟一性索引,但只能有一個主鍵。 3. 主鍵列不容許空值,而惟一性索引列容許空值。 5. 索引能夠提升查詢的速度。 建立Course的CouID的字段爲主鍵 Score的SID字段爲主鍵 Student的StdID字段爲主鍵 Teacher的TID字段爲主鍵