教务系统门户网站,广告创意设计是什么,wordpress 分类目录调用,市场调研公司介绍Python的DB-API,为大多数的数据库实现了接口,使用它连接各数据库后,就可以用相同的方式操作各数据库。Python DB-API使用流程:引入API模块。获取与数据库的连接。执行SQL语句和存储过程。关闭数据库连接。一、安装MySQL客户端MySQLdb 是用于Python链接Mysql数据库的接口#x…Python的DB-API,为大多数的数据库实现了接口,使用它连接各数据库后,就可以用相同的方式操作各数据库。Python DB-API使用流程:引入API模块。获取与数据库的连接。执行SQL语句和存储过程。关闭数据库连接。一、安装MySQL客户端MySQLdb 是用于Python链接Mysql数据库的接口它实现了 Python 数据库 API 规范 V2.0基于 MySQL C API 上建立的。如果是windows系统登录https://pypi.python.org/pypi/MySQL-python/1.2.5找到.exe结尾的包下载安装就好了然后在cmd中执行如果结果如上图所示则说明安装成功了。如果是Linux系统可以下载源码包进行安装https://pypi.python.org/pypi/MySQL-python/1.2.5中下载zip包然后安装yum install –y python-develyum install –y mysql-develyum install –y gccunzip MySQL-python-1.2.5.zipcd MySQL-python-1.2.5python setup.py buildpython setup.py installpython import MySQLdb二、数据库连接MySQLdb提供了connect方法用来和数据库建立连接,接收数个参数,返回连接对象代码如下:首先在mysql的数据库中建立python库create database python;connMySQLdb.connect(host192.168.203.12,usermomo,passwd123456,dbpython,charsetutf8)比较常用的参数包括:host:数据库主机名.默认是用本地主机user:数据库登陆名.默认是当前用户passwd:数据库登陆的秘密.默认为空db:要使用的数据库名.没有默认值port:MySQL服务使用的TCP端口.默认是3306数字类型charset:数据库编码推荐把所有数据库的配置写在一个字典中如下所示defconnect_mysql():db_config{host: 192.168.203.12,port: 3306,user: momo,passwd: 123456,db: python,charset: utf8}cnx MySQLdb.connect(**db_config)return cnx三、MySQL事物MySQL 事务主要用于处理操作量大复杂度高的数据。比如你操作一个数据库公司的一个员工离职了你要在数据库中删除他的资料也要删除该人员相关的比如邮箱个人资产等。这些数据库操作语言就构成了一个事务。在MySQL中只有使用了Innodb数据库引擎的数据库或表才支持事务所以很多情况下我们都使用innodb引擎。事务处理可以用来维护数据库的完整性保证成批的SQL语句要么全部执行要么全部不执行。一般来说事务是必须满足4个条件(ACID) Atomicity(原子性)、Consistency(稳定性)、Isolation(隔离性)、Durability(可靠性)1、事务的原子性一组事务要么成功要么撤回。2、稳定性 有非法数据(外键约束之类)事务撤回。3、隔离性事务独立运行。一个事务处理后的结果影响了其他事务那么其他事务会撤回。事务的100%隔离需要牺牲速度。4、可靠性软、硬件崩溃后InnoDB数据表驱动会利用日志文件重构修改。可靠性和高速度不可兼得 innodb_flush_log_at_trx_commit选项 决定什么时候吧事务保存到日志里。而mysql在默认的情况下他是把每个selectinsertupdatedelete等做为一个事务的登录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的selectinsertupdate等操作就会进行自动提交。如果把改选项关闭我们就可以每次执行完一次代码就需要进行手动提交connect对象给我们提供了两种办法来操作提交数据。a) mysql事务的方法commit():提交当前事务如果是支持事务的数据库执行增删改后没有commit则数据库默认回滚白操作了rollback():取消当前事务下面我们来看个例子我们先创建一个员工表create table employees (emp_no intnotnull auto_increment,emp_name varchar(16) notnull,gender enum(M, F) notnull,hire_date datenotnull,primary key (emp_no));其中emp_no为员工id为主键且唯一emp_name为员工的名字fender为性别只有M和F两种选择hire_date为雇佣的时间。为了试验的效果我们插入几条数据insert into employees(emp_no, emp_name, gender, hire_date) values(1001, lingjiang, M, 2015-04-01);insert into employees(emp_no, emp_name, gender, hire_date) values(1002, xiang, M, 2015-04-01);insert into employees(emp_no, emp_name, gender, hire_date) values(1003, shang, M, 2015-04-01);mysql select * fromemployees;---------------------------------------| emp_no | emp_name | gender | hire_date |---------------------------------------| 1001 | lingjiang | M | 2015-04-01 || 1002 | xiang | M | 2015-04-01 || 1003 | shang | M | 2015-04-01 |---------------------------------------e) rowsin set (0.00 sec)四、MySQL游标游标(cursor)游标是系统为用户开设的一个数据缓冲区存放SQL语句的执行结果用户可以用SQL语句逐一从游标中获取记录并赋给主变量交由python进一步处理一组主变量一次只能存放一条记录仅使用主变量并不能完全满足SQL语句向应用程序输出数据的要求。游标和游标的优点在数据库中游标是一个十分重要的概念。游标提供了一种对从表中检索出的数据进行操作的灵活手段就本质而言游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。游标总是与一条SQL 选择语句相关联因为游标由结果集(可以是零条、一条或由相关的选择语句检索出的多条记录)和结果集中指向特定记录的游标位置组成。当决定对结果集进行处理时必须声明一个指向该结果集的游标。常用方法:cursor():创建游标对象close():关闭此游标对象fetchone():得到结果集的下一行fetchmany([size cursor.arraysize]):得到结果集的下几行fetchall():得到结果集中剩下的所有行excute(sql[, args]):执行一个数据库查询或命令executemany (sql, args):执行多个数据库查询或命令程序例子1.创建游标对象import MySQLdbdb_config{host: 192.168.203.12,port: 3306,user: momo,passwd: 123456,db: python,charset: utf8}cnx MySQLdb.connect(**db_config)cus cnx.cursor()2.对游标的基本操作importMySQLdbdefconnect_mysql():db_config{host: 192.168.203.12,port: 3306,user: momo,passwd: 123456,db: python,charset: utf8}cnx MySQLdb.connect(**db_config)returncnxif __name__ __main__:cnxconnect_mysql()cuscnx.cursor()sql select * from employees;try:cus.execute(sql)result1cus.fetchone()print(result1:)print(result1)result2 cus.fetchmany(1)print(result2:)print(result2)result3cus.fetchall()print(result3:)print(result3) cus.close()cnx.commit()exceptException as e:cnx.rollback()print(error)raiseefinally:cnx.close()结果result1:(1001L, ulingjiang, uM, datetime.date(2015, 4, 1))result2:((1002L, uxiang, uM, datetime.date(2015, 4, 1)),)result3:((1003L, ushang, uM, datetime.date(2015, 4, 1)),)解释先通过MySQLdb.connect(**db_config)建立mysql连接对象在通过 cnx.cursor()创建游标fetchone():在最终搜索的数据中去一条数据fetchmany(1)在接下来的数据中在去1行的数据这个数字可以自定义定义多少就是在结果集中取多少条数据。fetchall()是在所有的结果中搞出来所有的数据。3.执行多行SQL语句#!/usr/bin/env python#-*- coding:utf-8 -*-#Time : 2017/9/18 22:17#Author : lingxiangxiang#File : domon3.pyfrom demon2 importconnect_mysqlimportMySQLdbdefconnect_mysql():db_config{host: 192.168.203.12,port: 3306,user: momo,passwd: 123456,db: python,charset: utf8}try:cnx MySQLdb.connect(**db_config)exceptException as e:raiseereturncnxif __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)cnxconnect_mysql()cuscnx.cursor()print(dir(cus))try:cus.execute(sql)cus.executemany(sql1, param)#help(cus.executemany)result1 cus.fetchone()print(result1)print(result1)result2 cus.fetchmany(3)print(result2)print(result2)result3cus.fetchall()print(result3)print(result3)cus.close()cnx.commit()exceptException as e:cnx.rollback()raiseefinally:cnx.close()五、数据库连接池python编程中可以使用MySQLdb进行数据库的连接及诸如查询/插入/更新等操作但是每次连接mysql数据库请求时都是独立的去请求访问相当浪费资源而且访问数量达到一定数量时对mysql的性能会产生较大的影响。因此实际使用中通常会使用数据库的连接池技术来访问数据库达到资源复用的目的。python的数据库连接池包 DBUtilsDBUtils是一套Python数据库连接池包并允许对非线程安全的数据库接口进行线程安全包装。DBUtils来自Webware for Python。DBUtils提供两种外部接口* PersistentDB 提供线程专用的数据库连接并自动管理连接。* PooledDB 提供线程间可共享的数据库连接并自动管理连接。PooledDB的参数1. mincached最少的空闲连接数如果空闲连接数小于这个数pool会创建一个新的连接2. maxcached最大的空闲连接数如果空闲连接数大于这个数pool会关闭空闲连接3. maxconnections最大的连接数4. blocking当连接数达到最大的连接数时在请求连接的时候如果这个值是True请求连接的程序会一直等待直到当前连接数小于最大连接数如果这个值是False会报错5. maxshared 当连接数达到这个数新请求的连接会分享已经分配出去的连接在uwsgi中每个http请求都会分发给一个进程连接池中配置的连接数都是一个进程为单位的(即上面的最大连接数都是在一个进程中的连接数)而如果业务中一个http请求中需要的sql连接数不是很多的话(其实大多数都只需要创建一个连接)配置的连接数配置都不需要太大。连接池对性能的提升表现在1.在程序创建连接的时候可以从一个空闲的连接中获取不需要重新初始化连接提升获取连接的速度2.关闭连接的时候把连接放回连接池而不是真正的关闭所以可以减少频繁地打开和关闭连接六、数据库的操作1.建表各个表的结构如下student表字段名类型是否为空主键描述StdIDint否是学生IDStdNamevarchar(100)否学生姓名Genderenum(M, F)是性别Agetinyint是年龄course表字段名类型是否为空主键描述CouIDint否是课程IDCnamevarchar(50)否课程名字TIDint否老师IDScore表字段名类型是否为空主键描述SIDint否是分数IDStdIDint否学生idCouIDint否课程idGradeint否分数teacher表字段名类型是否为空主键描述TIDint否是老师IDTnamevarcher(100)否老师名字在Linux中MySQL建立student表然后在Python代码中执行importMySQLdbdefconnect_mysql():db_config{host: 192.168.203.12,port: 3306,user: momo,passwd: 123456,db: student,charset: utf8}cnx MySQLdb.connect(**db_config)returncnxif __name__ __main__:cnxconnect_mysql()cuscnx.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;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()exceptException as e:cnx.rollback()print(error)raiseefinally:cnx.close()结果mysql show tables;------------------| Tables_in_python |------------------| Course || Score || Student || Teacher || tmp |------------------1 rows in set (0.00 sec)information_schema数据库表说明:SCHEMATA表提供了当前mysql实例中所有数据库的信息。是show databases的结果取之此表。TABLES表提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema表类型表引擎创建时间等信息。是show tables from schemaname的结果取之此表。COLUMNS表提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。是show columns from schemaname.tablename的结果取之此表。STATISTICS表提供了关于表索引的信息。是show index from schemaname.tablename的结果取之此表。USER_PRIVILEGES(用户权限)表给出了关于全程权限的信息。该信息源自mysql.user授权表。是非标准表。SCHEMA_PRIVILEGES(方案权限)表给出了关于方案(数据库)权限的信息。该信息来自mysql.db授权表。是非标准表。TABLE_PRIVILEGES(表权限)表给出了关于表权限的信息。该信息源自mysql.tables_priv授权表。是非标准表。COLUMN_PRIVILEGES(列权限)表给出了关于列权限的信息。该信息源自mysql.columns_priv授权表。是非标准表。CHARACTER_SETS(字符集)表提供了mysql实例可用字符集的信息。是SHOW CHARACTER SET结果集取之此表。COLLATIONS表提供了关于各字符集的对照信息。COLLATION_CHARACTER_SET_APPLICABILITY表指明了可用于校对的字符集。这些列等效于SHOW COLLATION的前两个显示字段。TABLE_CONSTRAINTS表描述了存在约束的表。以及表的约束类型。KEY_COLUMN_USAGE表描述了具有约束的键列。ROUTINES表提供了关于存储子程序(存储程序和函数)的信息。此时ROUTINES表不包含自定义函数(UDF)。名为“mysql.proc name”的列指明了对应于INFORMATION_SCHEMA.ROUTINES表的mysql.proc表列。VIEWS表给出了关于数据库中的视图的信息。需要有show views权限否则无法查看视图信息。TRIGGERS表提供了关于触发程序的信息。必须有super权限才能查看该表而TABLES在安装好mysql的时候一定是有数据的因为在初始化mysql的时候就需要创建系统表该表一定有数据。set i : 0;create table tmp as select (i : i 1) as id from information_schema.tables limit 10;mysql中变量不用事前申明在用的时候直接用“变量名”使用就可以了。set这个是mysql中设置变量的特殊用法当i需要在select中使用的时候必须加:这样就创建好了一个表tmp查看tmp的数据mysql select * from tmp;------| id|------|1 ||2 ||3 ||4 ||5 ||6 ||7 ||8 ||9 ||10 |------10 rows in set (0.00 sec)我们只是从information_schema.tables表中取10条数据任何表有10条数据也是可以的然后把变量i作为id列的值分10次不断输出依据最后select的结果创建表tmp。2.增加数据substr是一个字符串函数从第二个参数1,开始取字符取到3 floor(rand() * 75)结束floor函数代表的是去尾法取整数。rand()函数代表的是从0到1取一个随机的小数。rand() * 75就代表的是0到75任何一个小数3floor(rand() * 75)就代表的是3到77的任意一个数字concat()函数是一个对多个字符串拼接函数。sha1是一个加密函数sha1(rand())对生成的0到1的一个随机小数进行加密转换成字符串的形式。concat(sha1(rand()), sha1(rand()))就代表的是两个0-1生成的小数加密然后进行拼接。substr(concat(sha1(rand()), sha1(rand())), 1, floor(rand() * 80))就代表的是从一个随机生成的一个字符串的第一位开始取取到(随机3-77)位结束。Gender字段case floor(rand()*10) mod 2 when 1 then M else F end,就代表的是floor(rand()*10)代表0-9随机取一个数floor(rand()*10) mod 2 就是对0-9取得的随机数除以2的余数case floor(rand()*10) mod 2 when 1 then M else F end,代表当余数为1是就取M其他的为FAge字段25-floor(rand() * 5)代表的就是25减去一个0-4的一个整数代码如下importMySQLdbdefconnect_mysql():db_config{host: 192.168.203.12,port: 3306,user: momo,passwd: 123456,db: student,charset: utf8}cnx MySQLdb.connect(**db_config)returncnxif __name__ __main__:cnxconnect_mysql()students set i : 10000;insert into Student select i:i1, 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:i1, 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(1rand()*100) from tmp a, tmp b, tmp c, tmp d;theacher set i : 100;insert into Teacher select i:i1, substr(concat(sha1(rand()), sha1(rand())), 1, 5 floor(rand() * 80)) from tmp a, tmp b;try:cus_studentscnx.cursor()cus_students.execute(students)cus_students.close()cus_coursecnx.cursor()cus_course.execute(course)cus_course.close()cus_scorecnx.cursor()cus_score.execute(score)cus_score.close()cus_teachercnx.cursor()cus_teacher.execute(theacher)cus_teacher.close()cnx.commit()exceptException as e:cnx.rollback()print(error)raiseefinally:cnx.close()3.查数据在数据库中查出来所有名字有重复的同学的所有信息然后写入到文件中代码如下importcodecsimportMySQLdbdefconnect_mysql():db_config{host: 192.168.203.12,port: 3306,user: momo,passwd: 123456,db: student,charset: utf8}cnx MySQLdb.connect(**db_config)returncnxif __name__ __main__:cnxconnect_mysql()sql select * from Student where StdName in (select StdName from Student group by StdName having count(1)1 ) order by StdName;try:cuscnx.cursor()cus.execute(sql)resultcus.fetchall()with codecs.open(select.txt, w) as f:for line inresult:f.write(str(line))f.write(\n)cus.close()cnx.commit()exceptException as e:cnx.rollback()print(error)raiseefinally:cnx.close()解释:我们先来分析一下select查询这个语句select * from Student where StdName in (select StdName from Student group by StdName having count(1)1 ) order by StdName;我们先来看括号里面的语句select StdName from Student group by StdName having count(1)1这个是把所有学生名字重复的学生都列出来最外面select是套了一个子查询学生名字是在我们()里面的查出来的学生名字把这些学生的所有信息都列出来。result cus.fetchall()列出结果以后我们通过fetchall()函数把所有的内容都取出来这个result是一个tuple通过文件写入的方式我们把取出来的result写入到select.txt文件中。得到最终的结果4.删除数据删除课程成绩最差的5名老师删除之前要先进行查询。代码如下importcodecsimportMySQLdbdefconnect_mysql():db_config{host: 192.168.203.12,port: 3306,user: momo,passwd: 123456,db: student,charset: utf8}cnx MySQLdb.connect(**db_config)returncnxif __name__ __main__:cnxconnect_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 Courseleft join Score on Score.Grade 60 and Course.CouID Score.CouIDleft join Teacher on Course.TID Teacher.TIDgroup by Course.TIDorder by count_teacher desclimit 5) as test )try:cuscnx.cursor()cus.execute(sql)resultcus.fetchall()cus.close()cnx.commit()exceptException as e:cnx.rollback()print(error)raiseefinally:cnx.close()解释先查询出Course表中的Course.TID和Course.TIDleft join 是关联Score表查出Score.Grade 59并且课程ID和课程表的CouID要对应上left join Teacher 是关联老师表课程中的了老师ID和老师表中的老师ID对应上select中加上老师的名字Teacher.Tname和count(Teacher.TID)group by Course.TID在根据老师的的TID进行分组oder by 最后对count_teacher进行排序取前5行在通过套用一个select子查询把所有的TID搂出来然后delete from Teacher 最后删除TID在上表中的子查询中5.修改数据把分数低于5分的成绩加上60分代码如下importcodecsimportMySQLdbdefconnect_mysql():db_config{host: 192.168.203.12,port: 3306,user: momo,passwd: 123456,db: student,charset: utf8}cnx MySQLdb.connect(**db_config)returncnxif __name__ __main__:cnxconnect_mysql()sql select *, (grade60) as newGrade from Score where Grade 5;update update Score set grade grade 60 where grade 5;try:cus_startcnx.cursor()cus_start.execute(sql)result1cus_start.fetchall()print(len(result1))cus_start.close()cus_updatecnx.cursor()cus_update.execute(update)cus_update.close()cus_endcnx.cursor()cus_end.execute(sql)result2cus_end.fetchall()print(len(result2))cus_end.close()cnx.commit()exceptException as e:cnx.rollback()print(error)raiseefinally:cnx.close()解释刚开始我们可以查到分数小于5分的总个数有321个select *, (grade60) as newGrade from Score where Grade 5;这个sql是把所有的成绩小于5的都列出来然后最后加一列分数加60分的结果。update Score set grade grade 60 where grade 5;是把分数小于5的所有成绩都加60分最后在检查分数小于5的个数为0说明所有低于5分的分数都发生了改变。6.索引MySQL索引的概念索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分)它们包含着对数据表里所有记录的引用指针。更通俗的说数据库索引好比是一本书前面的目录能加快数据库的查询速度。索引类别普通索引普通索引(由关键字 KEY 或 INDEX 定义的索引)的唯一任务是加快对数据的访问速度。因此应该只为那些最经常出现在查询条件(WHERE column )或排序条件(ORDER BY column)中的数据列创建索引。只要有可能就应该选择一个数据最整齐、最紧凑的数据列(如一个整数类型的数据列)来创建索引。唯一索引普通索引允许被索引的数据列包含重复的值。比如说因为人有可能同名所以同一个姓名在同一个“员工个人资料”数据表里可能出现两次或更多次。如果能确定某个数据列将只包含彼此各不相同的值在为这个数据列创建索引的时候就应该用关键字UNIQUE 把它定义为一个唯一索引。这么做的好处一是简化了 MySQL 对这个索引的管理工作这个索引也因此而变得更有效率二是 MySQL 会在有新记录插入数据表时自动检查新记录的这个字段的值是否已经在某个记录的这个字段里出现过了如果是MySQL 将拒绝插入那条新记录。也就是说唯一索引可以保证数据记录的唯一性。事实上在许多场合人们创建唯一索引的目的往往不是为了提高访问速度而只是为了避免数据出现重复。主索引在前面已经反复多次强调过必须为主键字段创建一个索引这个索引就是所谓的“主索引”。主索引与唯一索引的唯一区别是前者在定义时使用的关键字是 PRIMARY 而不是 UNIQUE。外键索引如果为某个外键字段定义了一个外键约束条件MySQL 就会定义一个内部索引来帮助自己以最有效率的方式去管理和使用外键约束条件。复合索引索引可以覆盖多个数据列如像 INDEX (columnA, columnB) 索引。这种索引的特点是 MySQL 可以有选择地使用一个这样的索引。如果查询操作只需要用到 columnA 数据列上的一个索引就可以使用复合索引 INDEX(columnA, columnB)。不过这种用法仅适用于在复合索引中排列在前的数据列组合。比如说INDEX (ABC) 可以当做 A 或 (A,B) 的索引来使用但不能当做 B、C 或 (B,C) 的索引来使用。mysql主键和索引的区别:主键一定是唯一性索引唯一性索引并不一定就是主键。所谓主键就是能够唯一标识表中某一行的属性或属性组一个表只能有一个主键但可以有多个候选索引。因为主键可以唯一标识某一行记录所以可以确保执行数据更新、删除的时候不会出现张冠李戴的错误。主键除了上述作用外常常与外键构成参照完整性约束防止出现数据不一致。数据库在设计时主键起到了很重要的作用。主键可以保证记录的唯一和主键域非空数据库管理系统对于主键自动生成唯一索引所以主键也是一个特殊的索引。一个表中可以有多个唯一性索引但只能有一个主键。主键列不允许空值而唯一性索引列允许空值。索引可以提高查询的速度。创建Course的CouID的字段为主键 Score的SID字段为主键 Student的StdID字段为主键 Teacher的TID字段为主键代码如下importcodecsimportMySQLdbdefconnect_mysql():db_config{host: 192.168.203.12,port: 3306,user: momo,passwd: 123456,db: student,charset: utf8}cnx MySQLdb.connect(**db_config)returncnxif __name__ __main__:cnxconnect_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:cuscnx.cursor()cus.execute(sql1)cus.close()cuscnx.cursor()cus.execute(sql2)cus.close()cuscnx.cursor()cus.execute(sql3)cus.close()cuscnx.cursor()cus.execute(sql4)cus.close()cuscnx.cursor()cus.execute(sql5)cus.close()cuscnx.cursor()cus.execute(sql7)resultcus.fetchall()print(result)cus.close()cnx.commit()exceptException as e:cnx.rollback()print(error)raiseefinally:cnx.close()结果((1L, uSIMPLE, uScore, uref, uidx_StdID_CouID, uidx_StdID_CouID, u4, uconst, 4L, None),)解释Sql1 sql2 sql3 sql4是添加主键sql5是增加一个索引我们也可以在mysql的客户端上执行sq7得到如下的结果mysql explain select * from Score where StdID 16213;---------------------------------------------------------------------------------------------| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |---------------------------------------------------------------------------------------------| 1 | SIMPLE | Score | ref | idx_StdID_CouID | idx_StdID_CouID | 4 | const | 4 | NULL |---------------------------------------------------------------------------------------------1 row in set (0.00 sec)这个说明我们在搜索StdID的时候是走了idx_StdID_CouID索引的。