• [技术干货] 查看MySQL系统帮助
    无论在学习还是在实际工作中,我们都会经常遇到各种意想不到的困难,不能总是期望别人伸出援助之手来帮我们解决,而应该利用我们的智慧和能力攻克。那么如何才能及时解决学习 MySQL 时的疑惑呢?可以通过 MySQL 的系统帮助来解决遇到的问题。在 MySQL 中,查看帮助的命令是 HELP,语法格式如下:HELP 查询内容其中,查询内容为要查询的关键字。查询内容中不区分大小写。查询内容中可以包含通配符“%”和“_”,效果与 LIKE 运算符执行的模式匹配操作含义相同。例如,HELP 'rep%' 用来返回以 rep 开头的主题列表。查询内容可以使单引号引起来,也可以不使用单引号,为避免歧义,最好使用单引号引起来。使用 HELP 查询信息的具体示例如下。1)查询帮助文档目录列表可以通过 HELP contents 命令查看帮助文档的目录列表,运行结果如下:mysql> HELP'contents'; You asked for help about help category: "Contents" For more information, type 'help <item>', where <item> is one of the following categories:    Account Management      Administration    Compound Statements    Contents    Data Definition    Data Manipulation    Data Types    Functions    Geographic Features    Help Metadata    Language Structure    Plugins    Procedures    Storage Engines    Table Maintenance    Transactions    User-Defined Functions    Utility2)查看具体内容根据上面运行结果列出的目录,可以选择某一项进行查询。例如使用 HELP Data Types; 命令查看所支持的数据类型,运行结果如下:mysql> HELP 'Data Types'; You asked for help about help category: "Data Types" For more information, type 'help <item>', where <item> is one of the following topics:    AUTO_INCREMENT    BIGINT    BINARY    BIT    BLOB    BLOB DATA TYPE    BOOLEAN    CHAR    CHAR BYTE    DATE    DATETIME    DEC    DECIMAL    DOUBLE    DOUBLE PRECISION    ENUM    FLOAT    INT    INTEGER    LONGBLOB    LONGTEXT    MEDIUMBLOB    MEDIUMINT    MEDIUMTEXT    SET DATA TYPE    SMALLINT    TEXT    TIME    TIMESTAMP    TINYBLOB    TINYINT    TINYTEXT    VARBINARY    VARCHAR    YEAR DATA TYPE如果还想进一步查看某一数据类型,如 INT 类型,可以使用 HELP INT;命令,运行结果如下:mysql> HELP 'INT'; Name: 'INT' Description: INT[(M)] [UNSIGNED] [ZEROFILL] A normal-size integer. The signed range is -2147483648 to 2147483647. The unsigned range is 0 to 4294967295. URL: https://dev.mysql.com/doc/refman/5.7/en/numeric-type-overview.html运行结果中可以看到 INT 类型的帮助信息,包含类型描述、取值范围和官方手册中 INT 类型说明的 URL。另外,还可以查询某命令,例如使用 HELP CREATE TABLE 命令查询创建数据表的语法,运行结果如下所示:mysql> HELP 'CREATE TABLE' Name: 'CREATE TABLE' Description: Syntax: CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name     (create_definition,...)     [table_options]     [partition_options] CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name     [(create_definition,...)]     [table_options]     [partition_options]     [IGNORE | REPLACE]     [AS] query_expression拓展MySQL 提供了 4 张数据表来保存服务端的帮助信息,即使用 HELP 语法查看的帮助信息。执行语句就是从这些表中获取数据并返回给客户端的,MySQL 提供的 4 张数据表如下:help_category:关于帮助主题类别的信息help_keyword:与帮助主题相关的关键字信息help_relation:帮助关键字信息和主题信息之间的映射help_topic:帮助主题的详细内容
  • [技术干货] MySQL之范式的使用
    一、范式范式的英文名称是Normal Form,它是英国人E.F.Codd(关系数据库的老祖宗)在上个世纪70年代提出关系数据库模型后总结出来的。范式是关系数据库理论的基础,也是我们在设计数据库结构过程中所要遵循的规则和指导方法。目前有迹可寻的共有8种范式,依次是:1NF,2NF,3NF,BCNF,4NF,5NF,DKNF,6NF。通常所用到的只是前三个范式,即:第一范式(1NF),第二范式(2NF),第三范式(3NF)。第一范式(1NF)第一范式其实是关系型数据库的基础,即任何关系型数据库都是符合第一范式的。简单的将第一范式就是每一行的各个数据都是不可分割的,同一列中不能有多个值,如果出现重复的属性就需要定义一个新的尸实体。下面数据库便不符合第一范式:+------------+-------------------+ | workername | company      | +------------+-------------------+ | John    | ByteDance,Tencent | | Mike    | Tencent      | +------------+-------------------+上面描述的数据所表达的意思是,Mike在Tencent工作,而John同时在ByteDance和Tencent工作(假设这是可能的)。但是这种表达方式并不符合第一范式,即列的数据必须是不可分的,要满足第一范式,必须是下面的这种形式:+------------+-----------+ | workername | company  | +------------+-----------+ | Mike    | Tencent  | | John    | ByteDance | | John    | Tencent  | +------------+-----------+第二范式(2NF)首先,一个数据库要满足第二范式必须要先满足第一范式。我们先看一个表格:+----------+-------------+-------+ | employee | department | head | +----------+-------------+-------+ | Jones  | Accountint | Jones | | Smith  | Engineering | Smith | | Brown  | Accounting | Jones | | Green  | Engineering | Smith | +----------+-------------+-------+这个表描述了被雇佣者,工作部门和领导的关系。这个表所表示的关系在现实生活中是完全可能存在的,现在让我们考虑一个问题,如果Brown接任Accounting部门的领导,我们需要怎样对表进行修改?这个问题将会变得非常麻烦,因为我们会发现数据都耦合在一起了,你很难找到一个很好的能唯一确定每一行的判断条件来执行你的UPDATE语句。而我们把能够唯一表示数据库中表的一行的数据成为这个表的主键。 因此,没有主键的表是不符合第二范式的,也就是说符合第二范式的表需要规定主键。因此我们为了使上面的表符合第二范式,需要将它拆分为两个表:+----------+-------------+ | employee | department | +----------+-------------+ | Brown  | Accounting | | Green  | Engineering | | Jones  | Accounting | | Smith  | Engineering | +----------+-------------+ +-------------+-------+ | department | head | +-------------+-------+ | Accounting | Jones | | Engineering | Smith | +-------------+-------+在这两个表中,第一个表的主键为employee,第二个表的主键为department。在这种情况下,完成上面的问题就显得非常简单了。第三范式(3NF)一个关系型数据库要满足第三范式必须要先满足第二范式。将第三范式前,我们同样先看两个表:+-----------+-------------+---------+-------+ | studentid | studentname | subject | score | +-----------+-------------+---------+-------+ | 1     | Mike    | Math  | 96  | | 2     | John    | Chinese | 85  | | 3     | Kate    | History | 100  | +-----------+-------------+---------+-------+ +-----------+-----------+-------+ | subjectid | studentid | score | +-----------+-----------+-------+ | 101    | 1     | 96  | | 111    | 3     | 100  | | 201    | 2     | 85  | +-----------+-----------+-------+上面的两个表格的主键分别为studentid和subjectid,很显然两个表都符合第二范式。但是我们会发现这两个表有重复冗余的数据score。因此第三范式就是要消除冗余的数据,具体到上面的情况,就是两个表只有一个能够存在score这一列数据。那么怎么将这两个表联系起来呢,这里就出现了外键。如果两个表中有冗余重复的列,而且这个表中的一个非主键列在另一个表中是主键,那么我们为了消除冗余列可以把这个非主键列作为联系两个表的桥梁,也就是外键。 通过观察可以发现,studentid在第一个表中是主键,在第二个表中是非主键,所以他就是第二个表的外键。因此上述情况我们有了以下符合第三范式的写法:+-----------+-------------+---------+ | studentid | studentname | subject | +-----------+-------------+---------+ | 1     | Mike    | Math  | | 2     | John    | Chinese | | 3     | Kate    | History | +-----------+-------------+---------+ +-----------+-----------+-------+ | subjectid | studentid | score | +-----------+-----------+-------+ | 101    | 1     | 96  | | 111    | 3     | 100  | | 201    | 2     | 85  | +-----------+-----------+-------+可以发现在设定了外键之后,第一个表即使删除了score列,也可以通过studentid在第二个表中查找到相应的score的值,这样即消除了数据的冗余,又不会影响查找,满足第三范式。二、范式的优点和缺点范式的优点范式化的更新操作通常要比反范式化要快。当数据较好地范式化时,就只有很少或者没有重复的数据,所以只需要修改更少的数据。范式化的表通常都比较小,可以更好的放在内存中,所以执行操作会更快。很少有多余的数据意味着检索列表数据时更少需要DISTINCT或者GROUP BY语句。范式的缺点范式化的缺点就是通常需要关联。稍微复杂一些的查询语句在符合范式的数据库上都可能需要至少一次关联,也许更多,这不但代价昂贵,也可能使一些索引策略无效。
  • [技术干货] 数据库为何要建立索引的原因理解分享
    首先明白为什么索引会增加速度,DB在执行一条Sql语句的时候,默认的方式是根据搜索条件进行全表扫描,遇到匹配条件的就加入搜索结果集合。如果我们对某一字段增加索引,查询时就会先去索引列表中一次定位到特定值的行数,大大减少遍历匹配的行数,所以能明显增加查询的速度。那么在任何时候都应该加索引么?这里有几个反例:1、如果每次都需要取到所有表记录,无论如何都必须进行全表扫描了,那么是否加索引也没有意义了。2、对非唯一的字段,例如“性别”这种大量重复值的字段,增加索引也没有什么意义。3、对于记录比较少的表,增加索引不会带来速度的优化反而浪费了存储空间,因为索引是需要存储空间的,而且有个致命缺点是对于update/insert/delete的每次执行,字段的索引都必须重新计算更新。    那么在什么时候适合加上索引呢?我们看一个Mysql手册中举的例子,这里有一条sql语句:    SELECT c.companyID, c.companyName FROM Companies c, User u WHERE c.companyID = u.fk_companyID AND c.numEmployees >= 0 AND c.companyName LIKE '%i%' AND u.groupID IN (SELECT g.groupID FROM Groups g WHERE g.groupLabel = 'Executive')    这条语句涉及3个表的联接,并且包括了许多搜索条件比如大小比较,Like匹配等。在没有索引的情况下Mysql需要执行的扫描行数是 77721876行。而我们通过在companyID和groupLabel两个字段上加上索引之后,扫描的行数只需要134行。在Mysql中可以通过 Explain Select来查看扫描次数。可以看出来在这种联表和复杂搜索条件的情况下,索引带来的性能提升远比它所占据的磁盘空间要重要得多。    那么索引是如何实现的呢?大多数DB厂商实现索引都是基于一种数据结构——B树。因为B树的特点就是适合在磁盘等直接存储设备上组织动态查找表。B树的定义是这样的:一棵m(m>=3)阶的B树是满足下列条件的m叉树:    1、每个结点包括如下作用域(j, p0, k1, p1, k2, p2, ... ki, pi) 其中j是关键字个数,p是孩子指针    2、所有叶子结点在同一层上,层数等于树高h    3、每个非根结点包含的关键字个数满足[m/2-1]<=j<=m-1    4、若树非空,则根至少有1个关键字,若根非叶子,则至少有2棵子树,至多有m棵子树    看一个B树的例子,针对26个英文字母的B树可以这样构造: 可以看到在这棵B树搜索英文字母复杂度只为o(m),在数据量比较大的情况下,这样的结构可以大大增加查询速度。然而有另外一种数据结构查询的虚度比B树更快——散列表。Hash表的定义是这样的:设所有可能出现的关键字集合为u,实际发生存储的关键字记为k,而|k|比|u|小很多。散列方法是通过散列函数h将u映射到表T[0,m-1]的下标上,这样u中的关键字为变量,以h为函数运算结果即为相应结点的存储地址。从而达到可以在o(1)的时间内完成查找。    然而散列表有一个缺陷,那就是散列冲突,即两个关键字通过散列函数计算出了相同的结果。设m和n分别表示散列表的长度和填满的结点数,n/m为散列表的填装因子,因子越大,表示散列冲突的机会越大。    因为有这样的缺陷,所以数据库不会使用散列表来做为索引的默认实现,Mysql宣称会根据执行查询格式尝试将基于磁盘的B树索引转变为和合适的散列索引以追求进一步提高搜索速度。我想其它数据库厂商也会有类似的策略,毕竟在数据库战场上,搜索速度和管理安全一样是非常重要的竞争点。基本概念介绍:索引使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构,例如 employee 表的姓(lname)列。如果要按姓查找特定职员,与必须搜索表中的所有行相比,索引会帮助您更快地获得该信息。索引提供指向存储在表的指定列中的数据值的指针,然后根据您指定的排序顺序对这些指针排序。数据库使用索引的方式与您使用书籍中的索引的方式很相似:它搜索索引以找到特定值,然后顺指针找到包含该值的行。在数据库关系图中,您可以在选定表的“索引/键”属性页中创建、编辑或删除每个索引类型。当保存索引所附加到的表,或保存该表所在的关系图时,索引将保存在数据库中。有关详细信息,请参见创建索引。注意;并非所有的数据库都以相同的方式使用索引。有关更多信息,请参见数据库服务器注意事项,或者查阅数据库文档。作为通用规则,只有当经常查询索引列中的数据时,才需要在表上创建索引。索引占用磁盘空间,并且降低添加、删除和更新行的速度。在多数情况下,索引用于数据检索的速度优势大大超过它的。索引列可以基于数据库表中的单列或多列创建索引。多列索引使您可以区分其中一列可能有相同值的行。如果经常同时搜索两列或多列或按两列或多列排序时,索引也很有帮助。例如,如果经常在同一查询中为姓和名两列设置判据,那么在这两列上创建多列索引将很有意义。确定索引的有效性:检查查询的 WHERE 和 JOIN 子句。在任一子句中包括的每一列都是索引可以选择的对象。对新索引进行试验以检查它对运行查询性能的影响。考虑已在表上创建的索引数量。最好避免在单个表上有很多索引。检查已在表上创建的索引的定义。最好避免包含共享列的重叠索引。检查某列中唯一数据值的数量,并将该数量与表中的行数进行比较。比较的结果就是该列的可选择性,这有助于确定该列是否适合建立索引,如果适合,确定索引的类型。索引类型根据数据库的功能,可以在数据库设计器中创建三种索引:唯一索引、主键索引和聚集索引。有关数据库所支持的索引功能的详细信息,请参见数据库文档。提示:尽管唯一索引有助于定位信息,但为获得最佳性能结果,建议改用主键或唯一约束。唯一索引唯一索引是不允许其中任何两行具有相同索引值的索引。当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。例如,如果在 employee 表中职员的姓 (lname) 上创建了唯一索引,则任何两个员工都不能同姓。主键索引数据库表经常有一列或列组合,其值唯一标识表中的每一行。该列称为表的主键。在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。聚集索引在聚集索引中,表中行的物理顺序与键值的逻辑(索引)顺序相同。一个表只能包含一个聚集索引。如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。建立方式和注意事项最普通的情况,是为出现在where子句的字段建一个索引。为方便讲述,我们先建立一个如下的表。CREATE TABLE mytable (  id serial primary key,  category_id int not null default 0,  user_id int not null default 0,  adddate int not null default 0 );OK.如果你有不止一个选择条件呢?例如: SELECT * FROM mytable WHERE category_id=1 AND user_id=2;你的第一反应可能是,再给user_id建立一个索引。不好,这不是一个最佳的方法。你可以建立多重的索引。CREATE INDEX mytable_categoryid_userid ON mytable (category_id,user_id);注意到我在命名时的习惯了吗?我使用"表名_字段1名_字段2名"的方式。你很快就会知道我为什么这样做了。现在你已经为适当的字段建立了索引,不过,还是有点不放心吧,你可能会问,数据库会真正用到这些索引吗?测试一下就OK,对于大多数的数据库来说,这是很容易的,只要使用EXPLAIN命令:EXPLAIN  SELECT * FROM mytable WHERE category_id=1 AND user_id=2;  This is what Postgres 7.1 returns (exactly as I expected)  NOTICE: QUERY PLAN:  Index Scan using mytable_categoryid_userid on  mytable (cost=0.00..2.02 rows=1 width=16) EXPLAIN以上是postgres的数据,可以看到该数据库在查询的时候使用了一个索引(一个好开始),而且它使用的是我创建的第二个索引。看到我上面命名的好处了吧,你马上知道它使用适当的索引了。接着,来个稍微复杂一点的,如果有个ORDER BY字句呢?不管你信不信,大多数的数据库在使用order by的时候,都将会从索引中受益。SELECT * FROM mytable WHERE category_id=1 AND user_id=2  ORDER BY adddate DESC;很简单,就象为where字句中的字段建立一个索引一样,也为ORDER BY的字句中的字段建立一个索引:CREATE INDEX mytable_categoryid_userid_adddate  ON mytable (category_id,user_id,adddate);  注意: "mytable_categoryid_userid_adddate" 将会被截短为 "mytable_categoryid_userid_addda"  CREATE  EXPLAIN SELECT * FROM mytable WHERE category_id=1 AND user_id=2  ORDER BY adddate DESC;  NOTICE: QUERY PLAN:  Sort (cost=2.03..2.03 rows=1 width=16) -> Index Scan using mytable_categoryid_userid_addda  on mytable (cost=0.00..2.02 rows=1 width=16)  EXPLAIN看看EXPLAIN的输出,数据库多做了一个我们没有要求的排序,这下知道性能如何受损了吧,看来我们对于数据库的自身运作是有点过于乐观了,那么,给数据库多一点提示吧。为了跳过排序这一步,我们并不需要其它另外的索引,只要将查询语句稍微改一下。这里用的是postgres,我们将给该数据库一个额外的提示--在 ORDER BY语句中,加入where语句中的字段。这只是一个技术上的处理,并不是必须的,因为实际上在另外两个字段上,并不会有任何的排序操作,不过如果加入,postgres将会知道哪些是它应该做的。EXPLAIN SELECT * FROM mytable WHERE category_id=1 AND user_id=2  ORDER BY category_id DESC,user_id DESC,adddate DESC;  NOTICE: QUERY PLAN:  Index Scan Backward using mytable_categoryid_userid_addda on mytable  (cost=0.00..2.02 rows=1 width=16)  EXPLAIN现在使用我们料想的索引了,而且它还挺聪明,知道可以从索引后面开始读,从而避免了任何的排序。以上说得细了一点,不过如果你的数据库非常巨大,并且每日的页面请求达上百万算,我想你会获益良多的。不过,如果你要做更为复杂的查询呢,例如将多张表结合起来查询,特别是where限制字句中的字段是来自不止一个表格时,应该怎样处理呢?我通常都尽量避免这种做法,因为这样数据库要将各个表中的东西都结合起来,然后再排除那些不合适的行,搞不好开销会很大。如果不能避免,你应该查看每张要结合起来的表,并且使用以上的策略来建立索引,然后再用EXPLAIN命令验证一下是否使用了你料想中的索引。如果是的话,就OK。不是的话,你可能要建立临时的表来将他们结合在一起,并且使用适当的索引。要注意的是,建立太多的索引将会影响更新和插入的速度,因为它需要同样更新每个索引文件。对于一个经常需要更新和插入的表格,就没有必要为一个很少使用的where字句单独建立索引了,对于比较小的表,排序的开销不会很大,也没有必要建立另外的索引。以上介绍的只是一些十分基本的东西,其实里面的学问也不少,单凭EXPLAIN我们是不能判定该方法是否就是最优化的,每个数据库都有自己的一些优化器,虽然可能还不太完善,但是它们都会在查询时对比过哪种方式较快,在某些情况下,建立索引的话也未必会快,例如索引放在一个不连续的存储空间时,这会增加读磁盘的负担,因此,哪个是最优,应该通过实际的使用环境来检验。在刚开始的时候,如果表不大,没有必要作索引,我的意见是在需要的时候才作索引,也可用一些命令来优化表,例如MySQL可用"OPTIMIZE TABLE"。
  • [技术干货] MySQL升级版本后,导致现有配置无法正常连接到MySQL-server
    场景描述用户新建实例,用代码连接该数据库时出现报错:Caused by: javax.net.ssl.SSLException: Received fatal alert: protocol_versionMySQL原有版本为5.7.23,升级到5.7.25版本后,导致现有配置无法正常连接到MySQL-server,抓包结果如下图1:可以看出,客户端进行TLS握手时向服务端发送的TLS版本号是1.0,并提供了15个支持的密码套件。 连接失败抓包结果故障分析从MySQL-server的回复中可以看到,服务器拒绝了客户端的链接,原因是MySQL 5.7.25升级了openssl版本(1.1.1a),导致拒绝了不安全的TLS版本和密码套件。MySQL-server的回复解决方案升级您的JDK客户端到JDK 8或以上版本,则默认支持的TLS为1.2版本,如,可以正常连接的客户端支持TLS1.2,并支持30个密码套件。正常连接抓包结果
  • [技术干货] python 通过PYMYSQL使用MYSQL数据库方法
    什么是MYSQL数据库???MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。什么是PYMYSQL???PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2中则使用mysqldb。PyMySQL 遵循 Python 数据库 API v2.0 规范,并包含了 pure-Python MySQL 客户端库。PyMySQL安装1pip install pymysqlPyMySQL使用连接数据库1、首先导入PyMySQL模块2、连接数据库(通过connect())3、创建一个数据库对象 (通过cursor())4、进行对数据库做增删改查12345678910# coding:utf-8import pymysql# 连接数据库count = pymysql.connect(      host = 'xx.xxx.xxx.xx', # 数据库地址      port = 3306,  # 数据库端口号      user='xxxx',  # 数据库账号      password='XXXX',  # 数据库密码      db = 'test_sll')  # 数据库表名# 创建数据库对象db = count.cursor()查找数据db.fetchone()获取一条数据db.fetchall()获取全部数据123456789101112131415161718192021# coding:utf-8import pymysql# 连接数据库count = pymysql.connect(      host = 'xx.xxx.xxx.xx', # 数据库地址      port = 3306,  # 数据库端口号      user='xxxx',  # 数据库账号      password='xxxx',  # 数据库密码      db = 'test_sll')  # 数据库名称# 创建数据库对象db = count.cursor()# 写入SQL语句sql = "select * from students "# 执行sql命令db.execute(sql)# 获取一个查询# restul = db.fetchone()# 获取全部的查询内容restul = db.fetchall()print(restul)db.close()修改数据commit() 执行完SQL后需要提交保存内容123456789101112131415161718# coding:utf-8import pymysql# 连接数据库count = pymysql.connect(      host = 'xx.xxx.xxx.xx', # 数据库地址      port = 3306,  # 数据库端口号      user='xxx',  # 数据库账号      password='xxx',  # 数据库密码      db = 'test_sll')  # 数据库表名# 创建数据库对象db = count.cursor()# 写入SQL语句sql = "update students set age = '12' WHERE id=1"# 执行sql命令db.execute(sql)# 保存操作count.commit()db.close()删除数据123456789101112131415161718# coding:utf-8import pymysql# 连接数据库count = pymysql.connect(      host = 'xx.xxx.xxx.xx', # 数据库地址      port = 3306,  # 数据库端口号      user='xxxx',  # 数据库账号      password='xxx',  # 数据库密码      db = 'test_sll')  # 数据库表名# 创建数据库对象db = count.cursor()# 写入SQL语句sql = "delete from students where age = 12"# 执行sql命令db.execute(sql)# 保存提交count.commit()db.close()新增数据新增数据这里涉及到一个事务问题,事物机制可以保证数据的一致性,比如插入一个数据,不会存在插入一半的情况,要么全部插入,要么都不插入123456789101112131415161718# coding:utf-8import pymysql# 连接数据库count = pymysql.connect(      host = 'xx.xxx.xxx.xx', # 数据库地址      port = 3306,  # 数据库端口号      user='xxxx',  # 数据库账号      password='xxx',  # 数据库密码      db = 'test_sll')  # 数据库表名# 创建数据库对象db = count.cursor()# 写入SQL语句sql = "insert INTO students(id,name,age)VALUES (2,'安静','26')"# 执行sql命令db.execute(sql)# 保存提交count.commit()db.close()到这可以发现除了查询不需要保存,其他操作都要提交保存,并且还会发现删除,修改,新增,只是修改了SQL,其他的没什么变化创建表创建表首先我们先定义下表内容的字段字段名含义类型ididvarcharname姓名varcharage年龄int12345678910111213141516# coding:utf-8import pymysql# 连接数据库count = pymysql.connect(      host = 'xx.xxx.xxx.xx', # 数据库地址      port = 3306,  # 数据库端口号      user='xxxx',  # 数据库账号      password='xxx',  # 数据库密码      db = 'test_sll')  # 数据库表名# 创建数据库对象db = count.cursor()# 写入SQL语句sql = 'CREATE TABLE students (id VARCHAR(255) ,name VARCHAR(255) ,age INT)'# 执行sql命令db.execute(sql)db.close()感觉有用给个赞行不行????
  • [技术干货] 2020-12-26:mysql中,表person有字段id、name、age、sex,id是主键,name是普通索引,age和
    2020-12-26:mysql中,表person有字段id、name、age、sex,id是主键,name是普通索引,age和sex没有索引。select * from person where id=1 and name=james” and age=1 and sex=0。请问这条语句有几次回表?#福大大架构师每日一题#
  • [技术干货] MySQL数据库报错Native error 1461的解决方案
    场景描述MySQL用户通常在并发读写、大批量插入sql语句或数据迁移等场景出现如下报错信息:mysql_stmt_prepare failed! error(1461)Can't create more than max_prepared_stmt_count statements (current value: 16382)故障分析“max_prepared_stmt_count”的取值范围为0~1048576,默认为“16382”,该参数限制了同一时间在mysqld上所有session中prepared语句的上限,用户业务超过了该参数当前值的范围。解决方案请您调大“max_prepared_stmt_count”参数的取值,建议调整为“65535”。
  • [技术干货] MySQL是如何实现主备同步
    主备同步,也叫主从复制,是MySQL提供的一种高可用的解决方案,保证主备数据一致性的解决方案。在生产环境中,会有很多不可控因素,例如数据库服务挂了。为了保证应用的高可用,数据库也必须要是高可用的。因此在生产环境中,都会采用主备同步。在应用的规模不大的情况下,一般会采用一主一备。除了上面提到的数据库服务挂了,能够快速切换到备库,避免应用的不可用外,采用主备同步还有以下好处:提升数据库的读并发性,大多数应用都是读比写要多,采用主备同步方案,当使用规模越来越大的时候,可以扩展备库来提升读能力。备份,主备同步可以得到一份实时的完整的备份数据库。快速恢复,当主库出错了(比如误删表),通过备库来快速恢复数据。对于规模很大的应用,对于数据恢复速度的容忍性很低的情况,通过配置一台与主库的数据快照相隔半小时的备库,当主库误删表,就可以通过备库和binlog来快速恢复,最多等待半小时。说了主备同步是什么和好处,下面让我们来了解一下主备同步是怎么实现的。主备同步的实现原理下面以一个update语句来介绍主库与备库间是如何进行同步的。上图是一个update语句在节点A执行,然后同步到节点B的完整流程图,具体步骤有:主库接受到客户端发送的一条update语句,执行内部事务逻辑,同时写binlog。备库通过 change master 命令,设置主库的IP、端口、用户名和密码,以及要从哪个位置开始请求 binlog。这个位置包含文件名和偏移量。在备库上执行start slave命令,启动两个线程 io_thread 和 sql_thread,其中 io_thread 负责与主机进行连接。主库校验完用户名和密码,按照接收到的位置去读取binlog,发给备库。备库接收到binlog后,写到本地文件(relay log,中转文件)。备库读取中转文件,解析出命令,然后执行。主备同步的工作原理其实就是一个完全备份加上二进制日志备份的还原。不同的是这个二进制日志的还原操作基本上是实时的。备库通过两个线程来实现同步:一个是 I/O 线程,负责读取主库的二进制日志,并将其保存为中继日志。一个是 SQL 线程,负责执行中继日志。从上面的流程可以看出,主备同步的关键是binlog常见的俩种主备切换流程MS结构M-S结构,两个节点,一个当主库、一个当备库,不允许两个节点互换角色。对比前面的M-S结构图,可以发现,双M结构和M-S结构,其实区别只是多了一条线,即节点A和B之间总是互为主备关系。这样在切换的时候就不用再修改主备关系。双M结构的循环赋值问题在实际生产使用中,多数情况是使用双M结构的。但是,双M结构还有一个问题需要解决。业务逻辑在节点A执行更新,会生成binlog并同步到节点B。节点B同步完成后,也会生成binlog。(log_slave_updates设置为on,表示备库也会生成binlog)。当节点A同时也是节点B的备库时,节点B的binlog也会发送给节点A,造成循环复制。解决办法:设置节点的server-id,必须不同,不然不允许设置为主备结构备库在接到binlog后重放时,会记录原记录相同的server-id,即谁产生即为谁的。每个节点在接受binlog时,会判断server-id,如果是自己的就丢掉。解决后的流程:业务逻辑在节点A执行更新,会生成带有节点A的server-id的binlog。节点B接受到节点A发过来的binlog,并执行完成后,会生成带有节点A的server-id的binlog。节点A接受到binlog后,发现是自己的,就丢掉。死循环就在这里断掉了。
  • [技术干货] MySQL查看或显示数据库
    数据库可以看作是一个专门存储数据对象的容器,每一个数据库都有唯一的名称,并且数据库的名称都是有实际意义的,这样就可以清晰的看出每个数据库用来存放什么数据。在 MySQL 数据库中存在系统数据库和自定义数据库,系统数据库是在安装 MySQL 后系统自带的数据库,自定义数据库是由用户定义创建的数据库。在 MySQL 中,可使用 SHOW DATABASES 语句来查看或显示当前用户权限范围以内的数据库。查看数据库的语法格式为:SHOW DATABASES [LIKE '数据库名'];语法说明如下:LIKE 从句是可选项,用于匹配指定的数据库名称。LIKE 从句可以部分匹配,也可以完全匹配。数据库名由单引号' '包围。实例1:查看所有数据库列出当前用户可查看的所有数据库:mysql> SHOW DATABASES; +--------------------+ | Database           | +--------------------+ | information_schema | | mysql              | | performance_schema | | sakila             | | sys                | | world              | +--------------------+ 6 row in set (0.22 sec)可以发现,在上面的列表中有 6 个数据库,它们都是安装 MySQL 时系统自动创建的,其各自功能如下:information_schema:主要存储了系统中的一些数据库对象信息,比如用户表信息、列信息、权限信息、字符集信息和分区信息等。mysql:MySQL 的核心数据库,类似于 SQL Server 中的 master 表,主要负责存储数据库用户、用户访问权限等 MySQL 自己需要使用的控制和管理信息。常用的比如在 mysql 数据库的 user 表中修改 root 用户密码。performance_schema:主要用于收集数据库服务器性能参数。sakila:MySQL 提供的样例数据库,该数据库共有 16 张表,这些数据表都是比较常见的,在设计数据库时,可以参照这些样例数据表来快速完成所需的数据表。sys:MySQL 5.7 安装完成后会多一个 sys 数据库。sys 数据库主要提供了一些视图,数据都来自于 performation_schema,主要是让开发者和使用者更方便地查看性能问题。world:world 数据库是 MySQL 自动创建的数据库,该数据库中只包括 3 张数据表,分别保存城市,国家和国家使用的语言等内容。实例2:创建并查看数据库先创建一个名为 test_db 的数据库:mysql> CREATE DATABASE test_db;Query OK, 1 row affected (0.12 sec)再使用 SHOW DATABASES 语句显示权限范围内的所有数据库名,如下所示:mysql> SHOW DATABASES; +--------------------+ | Database           | +--------------------+ | information_schema | | mysql              | | performance_schema | | sakila             | | sys                | | test_db            | | world              | +--------------------+ 7 row in set (0.22 sec)你看,刚才创建的数据库已经被显示出来了。实例3:使用 LIKE 从句先创建三个数据库,名字分别为 test_db、db_test、db_test_db。1) 使用 LIKE 从句,查看与 test_db 完全匹配的数据库:mysql> SHOW DATABASES LIKE 'test_db'; +--------------------+ | Database (test_db) | +--------------------+ | test_db            | +--------------------+ 1 row in set (0.03 sec)2) 使用 LIKE 从句,查看名字中包含 test 的数据库:mysql> SHOW DATABASES LIKE '%test%'; +--------------------+ | Database (%test%)  | +--------------------+ | db_test            | +--------------------+ | db_test_db         | +--------------------+ | test_db            | +--------------------+ 3 row in set (0.03 sec)3) 使用 LIKE 从句,查看名字以 db 开头的数据库:mysql> SHOW DATABASES LIKE 'db%'; +----------------+ | Database (db%) | +----------------+ | db_test        | +----------------+ | db_test_db     | +----------------+ 2 row in set (0.03 sec)4) 使用 LIKE 从句,查看名字以 db 结尾的数据库:mysql> SHOW DATABASES LIKE '%db'; +----------------+ | Database (%db) | +----------------+ | db_test_db     | +----------------+ | test_db        | +----------------+ 2 row in set (0.03 sec)
  • [技术干货] MySQL null的一些易错点
    依据null-values,MySQL的值为null的意思只是代表没有数据,null值和某种类型的零值是两码事,比如int类型的零值为0,字符串的零值为””,但是它们依然是有数据的,不是null.我们在保存数据的时候,习惯性的把暂时没有的数据记为null,表示当前我们无法提供有效的信息.不过使用null但是时候,需要我们注意一些问题使用null的易错点下面我摘取MySQL官方给出的null的易错点做讲解.对MySQL不熟悉的人很容易搞混null和零值The concept of the NULL value is a common source of confusion for newcomers to SQL比如下面这2句SQL产生的数据是独立的mysql> INSERT INTO my_table (phone) VALUES (NULL); mysql> INSERT INTO my_table (phone) VALUES ('');第一句SQL只是表示暂时不知道电话号码是多少,第二句是电话号码知道并且记录为''Both statements insert a value into the phone column, but the first inserts a NULL value and the second inserts an empty string.  The meaning of the first can be regarded as “phone number is not known” and the meaning of the second can be regarded as  “the person is known to have no phone, and thus no phone number.”对null的逻辑判断要单独处理对于是否为null的判断必须使用专门的语法IS NULL,IS NOT NULL,IFNULL().To help with NULL handling, you can use the IS NULL and IS NOT NULL operators and the IFNULL() function.如果你使用=判断,那么永远是falseIn SQL, the NULL value is never true in comparison to any other value, even NULLTo search for column values that are NULL, you cannot use an expr = NULL test.  The following statement returns no rows, because expr = NULL is never true比如你这样写,where后判断的结果永不会是true:SELECT * FROM my_table WHERE phone = NULL;如果你使用null和其他数据做计算,那么结果永远是null,除非MySQL文档对某些操作做了额外的特殊说明An expression that contains NULL always produces a NULL value unless otherwise indicated  in the documentation for the operators and functions involved in the expression例如:mysql> SELECT NULL, 1+NULL, CONCAT('Invisible',NULL); +------+--------+--------------------------+ | NULL | 1+NULL | CONCAT('Invisible',NULL) | +------+--------+--------------------------+ | NULL |  NULL | NULL           | +------+--------+--------------------------+ 1 row in set (0.00 sec)所以你要对null做逻辑判断,还是乖乖的使用IS NULLTo look for NULL values, you must use the IS NULL test对有null值的列做索引要额外预料到隐藏的细节只有InnoDB,MyISAM,MEMORY 存储引擎支持给带有null值的列做索引You can add an index on a column that can have NULL values if you are using the MyISAM, InnoDB,  or MEMORY storage engine. Otherwise, you must declare an indexed column NOT NULL,  and you cannot insert NULL into the column.索引的长度会比普通索引大1,也就是略微耗内存点Due to the key storage format, the key length is one greater for a column that can be NULL than for a NOT NULL column.对null值做分组,去重,排序会被特殊对待和上文讲的=null永远是false相反,这时null 被认为是相等的.When using DISTINCT, GROUP BY, or ORDER BY, all NULL values are regarded as equal.对null排序会被特殊对待null值要么被排在最前面,要么最后面When using ORDER BY, NULL values are presented first, or last if you specify DESC to sort in descending order.聚合操作时null被忽略Aggregate (group) functions such as COUNT(), MIN(), and SUM() ignore NULL values例如count(*)不会统计值为null的数据.The exception to this is COUNT(*), which counts rows and not individual column values.  For example, the following statement produces two counts. The first is a count of the number of rows in the table,   and the second is a count of the number of non-NULL values in the age column:mysql> SELECT COUNT(*), COUNT(age) FROM person;
  • [技术干货] mysql的查询缓存说明
    工作原理查询缓存的工作原理,基本上可以概括为:缓存SELECT操作或预处理查询(注释:5.1.17开始支持)的结果集和SQL语句;新的SELECT语句或预处理查询语句,先去查询缓存,判断是否存在可用的记录集,判断标准:与缓存的SQL语句,是否完全一样,区分大小写;查询缓存对什么样的查询语句,无法缓存其记录集,大致有以下几类:查询语句中加了SQL_NO_CACHE参数;查询语句中含有获得值的函数,包涵自定义函数,如:CURDATE()、GET_LOCK()、RAND()、CONVERT_TZ等;对系统数据库的查询:mysql、information_schema查询语句中使用SESSION级别变量或存储过程中的局部变量;查询语句中使用了LOCK  IN SHARE MODE、FOR UPDATE的语句查询语句中类似SELECT …INTO 导出数据的语句;事务隔离级别为:Serializable情况下,所有查询语句都不能缓存;对临时表的查询操作;存在警告信息的查询语句;不涉及任何表或视图的查询语句;某用户只有列级别权限的查询语句;查询缓存的优缺点:不需要对SQL语句做任何解析和执行,当然语法解析必须通过在先,直接从Query  Cache中获得查询结果;查询缓存的判断规则,不够智能,也即提高了查询缓存的使用门槛,降低其效率;Query Cache的起用,会增加检查和清理Query Cache中记录集的开销,而且存在SQL语句缓存的表,每一张表都只有一个对应的全局锁;配置是否启用mysql查询缓存,可以通过2个参数:query_cache_type和query_cache_size,其中任何一个参数设置为0都意味着关闭查询缓存功能,但是正确的设置推荐query_cache_type=0。query_cache_type值域为:0 -– 不启用查询缓存;值域为:1 -– 启用查询缓存,只要符合查询缓存的要求,客户端的查询语句和记录集斗可以缓存起来,共其他客户端使用;值域为:2 -– 启用查询缓存,只要查询语句中添加了参数:sql_cache,且符合查询缓存的要求,客户端的查询语句和记录集,则可以缓存起来,共其他客户端使用;query_cache_size允许设置query_cache_size的值最小为40K,对于最大值则可以几乎认为无限制,实际生产环境的应用经验告诉我们,该值并不是越大, 查询缓存的命中率就越高,也不是对服务器负载下降贡献大,反而可能抵消其带来的好处,甚至增加服务器的负载,至于该如何设置,下面的章节讲述,推荐设置 为:64M;query_cache_limit限制查询缓存区最大能缓存的查询记录集,可以避免一个大的查询记录集占去大量的内存区域,而且往往小查询记录集是最有效的缓存记录集,默认设置为1M,建议修改为16k~1024k之间的值域,不过最重要的是根据自己应用的实际情况进行分析、预估来设置;query_cache_min_res_unit设置查询缓存分配内存的最小单位,要适当地设置此参数,可以做到为减少内存块的申请和分配次数,但是设置过大可能导致内存碎片数值上升。默认值为4K,建议设置为1k~16Kquery_cache_wlock_invalidate该参数主要涉及MyISAM引擎,若一个客户端对某表加了写锁,其他客户端发起的查询请求,且查询语句有对应的查询缓存记录,是否允许直接读取查询缓存的记录集信息,还是等待写锁的释放。默认设置为0,也即允许;维护查询缓区的碎片整理查询缓存使用一段时间之后,一般都会出现内存碎片,为此需要监控相关状态值,并且定期进行内存碎片的整理,碎片整理的操作语句:FLUSH QUERY CACHE;清空查询缓存的数据那些操作操作可能触发查询缓存,把所有缓存的信息清空,以避免触发或需要的时候,知道如何做,二类可触发查询缓存数据全部清空的命令:(1).RESET QUERY CACHE;(2).FLUSH TABLES;性能监控碎片率查询缓存内存碎片率=Qcache_free_blocks / Qcache_total_blocks * 100%命中率查询缓存命中率=(Qcache_hits – Qcache_inserts) / Qcache_hits * 100%内存使用率查询缓存内存使用率=(query_cache_size – Qcache_free_memory) / query_cache_size * 100%Qcache_lowmem_prunes该参数值对于检测查询缓存区的内存大小设置是否,有非常关键性的作用,其代表的意义为:查询缓存去因内存不足而不得不从查询缓存区删除的查询缓存信息,删除算法为LRU;query_cache_min_res_unit内存块分配的最小单元非常重要,设置过大可能增加内存碎片的概率发生,太小又可能增加内存分配的消耗,为此在系统平稳运行一个阶段性后,可参考公式的计算值:查询缓存最小内存块 = (query_cache_size – Qcache_free_memory) / Qcache_queries_in_cachequery_cache_size我们如何判断query_cache_size是否设置过小,依然也只有先预设置一个值,推荐为:32M~128M之间的区域,待系统平稳运行一个时间段(至少1周),并且观察这周内的相关状态值:(1).Qcache_lowmem_prunes;(2).命中率;(3).内存使用率;若整个平稳运行期监控获得的信息,为命中率高于80%,内存使用率超过80%,并且Qcache_lowmem_prunes的值不停地增加,而且增加的数值还较大,则说明我们为查询缓冲区分配的内存过小,可以适当地增加查询缓存区的内存大小;若是整个平稳运行期监控获得的信息,为命中率低于40%,Qcache_lowmem_prunes的值也保持一个平稳状态,则说明我们的查询缓冲区的内 存设置过大,或者说业务场景重复执行一样查询语句的概率低,同时若还监测到一定量的freeing items,那么必须考虑把查询缓存的内存条小,甚至关闭查询缓存功能;业务场景通过上述的知识梳理和分析,我们至少知道查询缓存的以下几点:查询缓存能够加速已经存在缓存的查询语句的速度,可以不用重新解析和执行而获得正确得记录集;查询缓存中涉及的表,每一个表对象都有一个属于自己的全局性质的锁;表若是做DDL、FLUSH TABLES 等类似操作,触发相关表的查询缓存信息清空;表对象的DML操作,必须优先判断是否需要清理相关查询缓存的记录信息,将不可避免地出现锁等待事件;查询缓存的内存分配问题,不可避免地产生一些内存碎片;查询缓存对是否是一样的查询语句,要求非常苛刻,而且还不智能;我们再重新回到本节的重点上,查询缓存适合什么样的业务场景呢?只要是清楚了查询缓存的上述优缺点,就不难罗列出来,业务场景要求:整个系统以读为主的业务,比如门户型、新闻类、报表型、论坛等网站;查询语句操作的表对象,非频繁地进行DML操作,可以使用query_cache_type=2模式,然后SQL语句加SQL_CACHE参数指定;
  • [技术干货] Mysql删除数据以及数据表的方法
    在Mysql 中删除数据以及数据表非常的容易,但是需要特别小心,因为一旦删除所有数据都会消失。删除数据删除表内数据,使用delete关键字。删除指定条件的数据删除用户表内id 为1 的用户:delete from User where id = 1;删除表内所有数据删除表中的全部数据,表结构不变。对于 MyISAM 会立刻释放磁盘空间,InnoDB 不会释放磁盘空间。delete from User;删除数据表删除数据表分为两种方式:删除数据表内数据以及表结构只删除表内数据,保留表结构drop使用drop关键词会删除整张表,啥都没有了。drop table User;truncatetruncate 关键字则只删除表内数据,会保留表结构。truncate table User;思考题:如何批量删除前缀相同的表?想要实现 drop table like 'wp_%',没有直接可用的命令,不过可以通过Mysql 的语法来拼接。-- 删除”wp_”开头的表: SELECT CONCAT( 'drop table ', table_name, ';' ) AS statement FROM information_schema.tables WHERE table_schema = 'database_name' AND table_name LIKE 'wp_%';其中database_name换成数据库的名称,wp_换成需要批量删除的表前缀。注意只有drop命令才能这样用:drop table if exists tablename`;truncate只能这样使用truncate table `tp_trade`.`setids`;总结当你不再需要该表时, 用drop;当你仍要保留该表,但要删除所有记录时, 用truncate;当你要删除部分记录时, 用delete。
  • [技术干货] MySQL处理无效数据值
    MySQL处理数据的基本原则是“垃圾进来,垃圾出去”,通俗一点说就是你传给 MySQL 什么样的数据,它就会存储什么样的数据。如果在存储数据时没有对它们进行验证,那么在把它们检索出来时得到的就不一定是你所期望的内容。 有几种 SQL 模式可以在遇到“非正常”值时抛出错误,如果你对其他数据库管理系统比较熟悉,会发现这种行为和其他的数据库管理系统很像。 下面介绍 MySQL 默认情况下如何处理非正常数据和启用各种 SQL 模式时会对数据处理产生哪些影响。 默认情况下,MySQL 会按照以下规则来处理越界(即超出取值范围)的值和其他非正常值:对于数值列或 TIME 列,超出合法取值范围的那些值将被截断到取值范围最近的那个端点,并把结果值存储起来。对于除 TIME 列以外的其他类型列,非法值会被转换成与该类型一致的“零”值。对于字符串列(不包括 ENUM 或 SET),过长的字符串将被截断到该列的最大长度。给 ENUM 或 SET 类型列进行赋值时,需要根据列定义里给出的合法取值列表进行。如果把不是枚举成员的值赋给 ENUM 列,那么列的值就会变成空字符串。如果把包含非集合成员的子字符串的值赋给 SET 列,那么这些字符串会被清理,剩余的成员才会被赋值给列。 如果在执行增删改查等语句时发生了上述转换,那么 MySQL 会给出警告消息。在执行完其中的某一条语句之后,可以使用 SHOW WARNINGS 语句来查看警告消息的内容。 如果需要在插入或更新数据时执行更严格的检查,那么可以启用以下两种 SQL 模式中的一种:SET sql_mode = 'STRICT_ALL_TABLES' ;SET sql_mode = 'STRICT_TRANS_TABLES';对于支持事务的表,这两种模式都是一样的。如果发现某个值无效或缺失,那么会产生一个错误,并且语句会中止执行,并进行回滚,就像什么事都没发生过一样。 对于不支持事务的表,这两种模式有以下效果。 1) 对于这两种模式,如果在插入或修改第一个行时,发现某个值无效或缺失,那么结果会产生一个错误,语句会中止执行,就像什么事都未发生过一样。 这跟事务表的行为很相似。 2) 在用于插入或修改多个行的语句里,如果在第一行之后的某个行出现了错误,那么会出现某些行被修改的情况。这两种模式决定着,这条语句此时此刻是要停止执行,还是要继续执行。在 STRICT_ALL_TABLES 模式下,会抛出一个错误,并且语句会停止执行。因为受该语句影响的许多行都已被修改,所以这将会导致“部分更新”问题。在 STRICT_TRANS_TABLES 模式下,对于非事务表,MySQL 会中止语句的执行。只有这样做,才能达到事务表那样的效果。只有当第一行发生错误时,才能达到这样的效果。如果错误在后面的某个行上,那么就会出现某些行被修改的情况。由于对于非事务表,那些修改是无法撤销的,因此 MySQL 会继续执行该语句,以避免出现“部分更新”的问题。它会把所有的无效值转换为与其最接近的合法值。对于缺失的值,MySQL 会把该列设置成其数据类型的隐式默认值, 通过以下模式可以对输入的数据进行更加严格的检查:ERROR_ FOR_ DIVISION_ BY_ ZERO:在严格模式下,如果遇到以零为除数的情况,它会阻止数值进入数据库。如果不在严格模式下,则会产生一条警告消息,并插入 NULL。NO_ ZERO_ DATE:在严格模式下,它会阻止“零”日期值进入数据库。NO_ ZERO_ IN_ DATE:在严格模式下,它会阻止月或日部分为零的不完整日期值进入数据库。 简单来说,MySQL 的严格模式就是 MySQL 自身对数据进行的严格校验,例如格式、长度、类型等。比如一个整型字段我们写入一个字符串类型的数据,在非严格模式下 MySQL 不会报错。如果定义了 char 或 varchar 类型的字段,当写入或更新的数据超过了定义的长度也不会报错。 虽然我们会在代码中做数据校验,但一般认为非严格模式对于编程来说没有任何好处。MySQL开启严格模式从一定程序上来讲也是对我们代码的一种测试,如果我们没有开启严格模式并且在开发过程中也没有遇到错误,那么在上线或代码移植的时候将有可能出现不兼容的情况,因此在开发过程做最好开启 MySQL 的严格模式。 可通过select @@sql_mode;命令查看当前是严格模式还是非严格模式。 例如,如果想让所有的存储引擎启用严格模式,并对“被零除”错误进行检查,那么可以像下面这样设置 SQL 模式:SET sql_mode ‘STRICT_ALL_TABLES, ERROR_FOR_DIVISION_BY_ZERO' ; 如果想启用严格模式,以及所有的附加限制,那么最为简单的办法是启用 TRADITIONAL 模式:SET sql_ mode ‘TRADITIONAL' ;TRADITIONAL 模式的含义是“启用严格模式,当向 MySQL 数据库插入数据时,进行数据的严格校验,保证错误数据不能插入。用于事务表时,会进行事务的回滚”。 可以选择性地在某些方面弱化严格模式。如果启用了 SQL 的 ALLOW_ INVALID_ DATES 模式,那么MySQL将不会对日期部分做全面检查。相反,它只会要求月份值在 1~12 之间,而天数处于 1~31 之间,即允许像‘2000-02-30’或‘2000-06-31’这样的无效值。 另一个制止错误的办法是在 INSERT 或 UPDATE 语句里使用 IGNORE 关键字。这样那些会因无效值而导致错误的语句,将只会导致警告的出现。这些选项能让你灵活地为你的应用选择正确的有效性检查级别。
  • [技术干货] MySql带OR关键字的多条件查询语句
    MySQL带OR关键字的多条件查询,与AND关键字不同,OR关键字,只要记录满足任意一个条件,就会被查询出来。SELECT * | {字段名1,字段名2,……} FROM 表名 WHERE 条件表达式1 OR 条件表达式2 […… OR 条件表达式n];查询student表中,id字段值小于15,或者gender字段值为nv的学生姓名可以看出,返回的5条记录中,3条记录的id字段值小于15,或者gender字段值为nv的记录查询student表中,name字段值以字符“h”开始,或者grade字段值为100的记录可以看出,查询出了符合条件的记录OR和AND关键字一起使用的情况OR关键字和AND关键字,可以一起使用,需要注意,AND的优先级高于OR。因此,当两者一起使用时,应该先运算AND两边的条件表达式,再运算OR两边的条件表达式查询student表中,gender字段值为nv,或者gender字段值为na,并且,grade字段值为100的学生姓名可以看出如果AND的优先级,和OR相同或者比OR低,AND操作会最后执行,查询结果会返回一条记录这里,返回了三条记录,说明,先执行的是AND操作,后执行的是OR操作,即AND的优先级高于OR
  • [技术干货] Mysql带And关键字的多条件查询语句
    MySQL带AND关键字的多条件查询,MySQL中,使用AND关键字,可以连接两个或者多个查询条件,只有满足所有条件的记录,才会被返回。SELECT * | {字段名1,字段名2,……} FROM 表名 WHERE 条件表达式1 AND 条件表达式2 […… AND 条件表达式n];查询student表中,id字段值小于16,并且,gender字段值为nv的学生姓名可以看出,查询条件必须都满足,才会返回查询student表中,id字段值在12、13、14、15之中,name字段值以字符串“ng”结束,并且,grade字段值小于80的记录可以看出,返回的记录,同时满足了AND关键字连接的三个条件表达式。假设有这样两条数据:(表名为user)1) username=admin,password=0000002) username=admin,password=123456我们要实现的效果是可以输入多个关键字查询,多个关键字间以逗号分隔。使用上述表举例:输入单个关键字“admin”可查出这两条数据,输入“admin,000000”只查出第一条数据,可实现的sql语句是:select * from user where concat(username, password) like '%admin%'; select * from user where concat(username, password) like '%admin%' and concat(username, password) like '%000000%';concat的作用是连接字符串,但这样有一个问题:如果你输入单个关键字“admin000000”也会查到第一条数据,这显然不是我们想要的结果,解决方法是:由于使用逗号分隔多个关键字,说明逗号永远不会成为关键字的一部分,所以我们在连接字符串时把每个字段以逗号分隔即可解决此问题,下面这个sql语句不会查询到第一条数据:select * from user where concat(username, ',', password) like '%admin000000%';如果分隔符是空格或其他符号,修改 ',' 为 '分隔符' 即可。总结:select * from 表名 where concat(字段1, '分隔符', 字段2, '分隔符', ...字段n) like '%关键字1%' and concat(字段1, '分隔符', 字段2, '分隔符', ...字段n) like '%关键字2%' ......;
总条数:1406 到第 页
上滑加载中