Python連接MySQL數據庫

linux和windows下安裝並啓動mysql數據庫

python安裝MySQLdb包,建議使用pip安裝

pip使用方法如下:

yum install python-pip    (優先安裝python-pip才能使用pip)

pip類似於linux中的yum

pip install ipython    (安裝python補全工具)

pip uninstall ipython    (使用pip卸載ipython)

pip list    (查看安裝了哪些包)

pip install ipython==1.2.1    (適用於python2.6的版本)


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 codecs

import MySQLdb

def connect_mysql():

    db_config = {

        'host': '192.168.1.1',

        'port': 3306,

        'user': 'zabbix',

        'passwd': '123456',

        'db': 'python',

        '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()

查看查詢是否走索引需要加explain關鍵字,如mysql> explain select * from Score where StdID = 16213;



python連接mysql

例子:

定義一個connect_mysql函數,在函數中指定mysql連接參數,如下所示

import MySQLdb

def connect_mysql():

    db_config = {

        'host': '192.168.1.1',

        'port': 3306,

        'user': 'zabbix',

        'passwd': '123456',

        'db': 'zabbix_user',

        'charset': 'utf8'

    }

try:

    cnx = MySQLdb.connect(**db_config)

except Exception as e:

        raise e

    return cnx

connect_mysql()


遊標操作

例子:

import MySQLdb

def connect_mysql():

    db_config = {

        'host': '192.168.1.1',

        'port': 3306,

        'user': 'zabbix',

        'passwd': '123456',

        'db': 'python',

        'charset': 'utf8'

    }

    try:

    cnx = MySQLdb.connect(**db_config)

except Exception as e:

        raise e

    return cnx

if __name__ == '__main__':

    cnx = connect_mysql()

    #cursor():創建遊標對象

    cus = cnx.cursor()

    sql  = '''create table test(id int not null);insert into test(id) values (100);'''

    try:

        #excute(sql[, args]):執行一個數據庫查詢或命令

        cus.execute(sql)

#close():關閉此遊標對象

        cus.close()

#提交遊標對象

        cnx.commit()

    except Exception as e:

#回滾遊標對象到commi之前

        cnx.rollback()

        raise e

    finally:

        cnx.close()


例子2:

#fetch函數的用法

#可以將例子1中的函數直接導入到此例子中使用,如下

#from 例子1 import connect_mysql

import MySQLdb

def connect_mysql():

    db_config = {

        'host': '192.168.1.1',

        'port': 3306,

        'user': 'zabbix',

        'passwd': '123456',

        'db': 'python',

        'charset': 'utf8'

    }

    cnx = MySQLdb.connect(**db_config)

    return cnx

if __name__ == '__main__':

    cnx = connect_mysql()

    #創建遊標對象

    cus = cnx.cursor()

    sql  = '''select * from zabbix_user;'''

    try:

        cus.execute(sql)

#查看一行

        result1 = cus.fetchone()

        print('result1:')

        print(result1)

#查看兩行,接着上次查詢開始

        result2 = cus.fetchmany(2)

        print('result2:')

        print(result2)

#查看剩餘所有行內容

        result3 = cus.fetchall()

        print('result3:')

        print(result3)

cus.close()

        cnx.commit()

    except Exception as e:

        cnx.rollback()

        print('error')

        raise e

    finally:

        cnx.close()

例子3:

#運行多個sql語句

import MySQLdb

def connect_mysql():

    db_config = {

        "host": "192.168.1.1",

        "port": 3306,

        "user": "xiang",

        "passwd": "123456",

        "db": "python",

        "charset": "utf8"

    }

    try:

        cnx = MySQLdb.connect(**db_config)

    except Exception as e:

        raise e

    return cnx

if __name__ == "__main__":

    sql = "select * from tmp;"

    sql1 = "insert into tmp(id) value (%s);"

    param = []

    for i in xrange(100, 130):

        param.append([str(i)])

    print(param)

    cnx = connect_mysql()

    cus = cnx.cursor()

    print(dir(cus))

    try:

        cus.execute(sql)

        cus.executemany(sql1, param)

        result1 = cus.fetchone()

        print("result1")

        print(result1)

        result2 = cus.fetchmany(3)

        print("result2")

        print(result2)

        result3 = cus.fetchall()

        print("result3")

        print(result3)

        cus.close()

        cnx.commit()

    except Exception as e:

        cnx.rollback()

        raise e

    finally:

        cnx.close()

數據庫連接池的使用方法

python編程中可以使用MySQLdb進行數據庫的連接及諸如查詢/插入/更新等操作,但是每次連接mysql數據庫請求時,都是獨立的去請求訪問,相當浪費資源,而且訪問數量達到一定數量時,對mysql的性能會產生較大的影響。因此,實際使用中,通常會使用數據庫的連接池技術,來訪問數據庫達到資源複用的目的。

python的數據庫連接池包 DBUtils,可以使用pip安裝

例子1:

import MySQLdb

from DBUtils.PooledDB import PooledDB

db_config = {

        "host": "192.168.1.1",

        "port": 3306,

        "user": "zabbix",

        "passwd": "123456",

        "db": "python",

        "charset": "utf8"

    }

#連接池裏的最少連接數爲5

pool = PooledDB(MySQLdb, 5, **db_config)

#以後每次需要數據庫連接就是用connection()函數獲取連接就好了

conn = pool.connection()

cur = conn.cursor()

SQL = "select * from tmp;"

r = cur.execute(SQL)

r = cur.fetchall()

print(r)

cur.close()

conn.close()


MySQL表的建立

例子:

import MySQLdb

def connect_mysql():

    db_config = {

        'host': '192.168.48.128',

        'port': 3306,

        'user': 'xiang',

        'passwd': '123456',

        'db': 'python',

        'charset': 'utf8'

    }

    cnx = MySQLdb.connect(**db_config)

    return cnx

if __name__ == '__main__':

    cnx = connect_mysql()

    cus = cnx.cursor()

    # sql  = '''insert into student(id, name, age, gender, score) values ('1001', 'ling', 29, 'M', 88), ('1002', 'ajing', 29, 'M', 90), ('1003', 'xiang', 33, 'M', 87);'''

    student = '''create table Student(

            StdID int not null,

            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;

            #mysql中變量不用事前申明,在用的時候直接用“@變量名”使用就可以了。set這個是mysql中設置變量的特殊用法,當@i需要在select中使用的時候,必須加:

            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(thearch)

    cus.execute(tmp)

        cus.close()

        cnx.commit()

    except Exception as e:

        cnx.rollback()

        print('error')

        raise e

    finally:

        cnx.close()

MySQL數據的建立

例子:

import MySQLdb

def connect_mysql():

    db_config = {

        'host': '192.168.48.128',

        'port': 3306,

        'user': 'xiang',

        'passwd': '123456',

        'db': 'python',

        'charset': 'utf8'

    }

    cnx = MySQLdb.connect(**db_config)

    return cnx

if __name__ == '__main__':

    cnx = connect_mysql()

    students = '''set @i := 10000;

            #floor()函數表示去尾法取整;rand()函數代表的是從0到1取一個隨機的小數;3+floor(rand() * 75)就代表的是:3到77的任意一個數字;concat()函數是一個對多個字符串拼接函數;sha1()是一個加密函數,sha1(rand())對生成的0到1的一個隨機小數進行加密,轉換成字符串的形式;

            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()

MySQL數據的查詢

例子:

import codecs

import MySQLdb

def connect_mysql():

    db_config = {

        'host': '192.168.48.128',

        'port': 3306,

        'user': 'xiang',

        'passwd': '123456',

        'db': 'python',

        'charset': 'utf8'

    }

    cnx = MySQLdb.connect(**db_config)

    return cnx

if __name__ == '__main__':

    cnx = connect_mysql()

    #()中的sql語句是把所有學生名字重複的學生都列出來;此sql是關聯查詢

    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()

Python操作刪除數據

例子:

import codecs

import MySQLdb

def connect_mysql():

    db_config = {

        'host': '192.168.1.1',

        'port': 3306,

        'user': 'zabbix',

        'passwd': '123456',

        'db': 'python',

        'charset': 'utf8'

    }

    cnx = MySQLdb.connect(**db_config)

    return cnx

if __name__ == '__main__':

    cnx = connect_mysql()

    #聯結查詢,將分數<60的老師查出,並針對不及格人數排序,只列出人數最多的5人;刪除操作必須針對一個表,後面as test是作此操作

    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()

Python操作修改數據

例子:

import codecs

import MySQLdb

def connect_mysql():

    db_config = {

        'host': '192.168.1.1',

        'port': 3306,

        'user': 'zabbix',

        'passwd': '123456',

        'db': 'python',

        'charset': 'utf8'

    }

    cnx = MySQLdb.connect(**db_config)

    return cnx

if __name__ == '__main__':

    cnx = connect_mysql()

    #將小於5分的所有學生查出

    sql = '''select *, (grade+60) as newGrade from Score where Grade <5;'''

    #將所有小於五分的學生成績都加60

    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()


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章