金色的骷髅 发表于 2015-1-16 20:08:45

绝无经由的透视MySQL数据库之更新语句

越来越多的开发者将继续选择MySQL。Evans的总裁JohnAndrews表示,MySQL学习教程用户对MySQL和其他开源数据库的评价正在赶上甚至超过很多专有商业数据库软件。用于操纵数据库的SQL一样平常分为两种,一种是查询语句,也就是我们所说的SELECT语句,别的一种就是更新语句,也叫做数据操纵语句。弦外之音,就是对数据举行修正。在尺度的SQL中有3个语句,它们是INSERT、UPDATE和DELETE。在MySQL中又多了一个REPLACE语句,因而,本文以MySQL为背景来会商怎样使有SQL中的更新语句。
1、INSERT和REPLACE
INSERT和REPLACE语句的功效都是向表中拔出新的数据。这两条语句的语法相似。它们的次要区分是怎样处置反复的数据。
1.INSERT的一样平常用法
MySQL中的INSERT语句和尺度的INSERT不太一样,在尺度的SQL语句中,一次拔出一笔记录的INSERT语句只要一种情势。
INSERTINTOtablename(列名…)VALUES(列值);
而在MySQL中另有别的一种情势。
INSERTINTOtablenameSETcolumn_name1=value1,column_name2=value2,…;
第一种办法将列名和列值分隔了,在利用时,列名必需和列值的数分歧。以下面的语句向users表中拔出了一笔记录:
INSERTINTOusers(id,name,age)VALUES(123,姚明,25);
第二种办法同意列名和列值成对呈现和利用,以下面的语句将发生中样的效果。
INSERTINTOusersSETid=123,name=姚明,age=25;
假如利用了SET体例,必需最少为一列赋值。假如某一个字段利用了省缺值(如默许或自增值),这两种办法都能够省略这些字段。如id字段上利用了自增值,下面两条语句能够写成以下情势:
INSERTINTOusers(name,age)VALUES(姚明,25);
INSERTINTOusesSETname=姚明,age=25;
MySQL在VALUES上也做了些变更。假如VALUES中甚么都不写,那MySQL将利用表中每列的默许值来拔出新纪录。
INSERTINTOusers()VALUES();
假如表名后甚么都不写,就暗示向表中一切的字段赋值。利用这类体例,不但在VALUES中的值要和列数分歧,并且按次不克不及倒置。INSERTINTOusersVALUES(123,姚明,25);
假如将INSERT语句写成以下情势MySQL将会报错。
INSERTINTOusersVALUES(姚明,25);
2.利用INSERT拔出多笔记录
看到这个题目大概人人会问,这有甚么好说的,挪用屡次INSERT语句不就能够拔出多笔记录了吗!但利用这类办法要增添服务器的负荷,由于,实行每次SQL服务器都要一样对SQL举行剖析、优化等操纵。幸亏MySQL供应了另外一种办理计划,就是利用一条INSERT语句来拔出多笔记录。这并非尺度的SQL语法,因而只能在MySQL中利用。
INSERTINTOusers(name,age)
VALUES(姚明,25),(比尔.盖茨,50),(火星人,600);
下面的INSERT语句向users表中一连拔出了3笔记录。值得注重的是,下面的INSERT语句中的VALUES后必需每笔记录的值放到一对(…)中,两头利用","支解。假定有一个表table1
CREATETABLEtable1(nINT);
假如要向table1中拔出5笔记录,上面写法是毛病的:
INSERTINTOtable1(i)VALUES(1,2,3,4,5);
MySQL将会抛出上面的毛病
ERROR1136:Columncountdoesntmatchvaluecountatrow1
而准确的写法应当是如许:
INSERTINTOtable1(i)VALUES(1),(2),(3),(4),(5);
固然,这类写法也能够省略列名,如许每对括号里的值的数量必需分歧,并且这个数量必需和列数分歧。如:
INSERTINTOtable1VALUES(1),(2),(3),(4),(5);
3.REPLACE语句
我们在利用数据库时大概会常常碰到这类情形。假如一个表在一个字段上创建了独一索引,当我们再向这个表中利用已存在的键值拔出一笔记录,那将会抛出一个主键抵触的毛病。固然,我们大概想用新纪录的值来掩盖本来的纪录值。假如利用传统的做法,必需先利用DELETE语句删除本来的纪录,然后再利用INSERT拔出新的纪录。而在MySQL中为我们供应了一种新的办理计划,这就是REPLACE语句。利用REPLACE拔出一笔记录时,假如不反复,REPLACE就和INSERT的功效一样,假如有反复纪录,REPLACE就利用新纪录的值来交换本来的纪录值。
利用REPLACE的最年夜优点就是能够将DELETE和INSERT合二为一,构成一个原子操纵。如许就能够不用思索在同时利用DELETE和INSERT时增加事件等庞大操纵了。
在利用REPLACE时,表中必需有独一索引,并且这个索引地点的字段不克不及同意空值,不然REPLACE就和INSERT完整一样的。
在实行REPLACE后,体系前往了所影响的行数,假如前往1,申明在表中并没有反复的纪录,假如前往2,申明有一条反复纪录,体系主动先挪用了DELETE删除这笔记录,然后再纪录用INSERT来拔出这笔记录。假如前往的值年夜于2,那申明有多个独一索引,有多笔记录被删除和拔出。
REPLACE的语法和INSERT十分的类似,以下面的REPLACE语句是拔出或更新一笔记录。
REPLACEINTOusers(id,name,age)VALUES(123,赵本山,50);
拔出多笔记录:
REPLACEINTOusers(id,name,age)
VALUES(123,赵本山,50),(134,Mary,15);
REPLACE也能够利用SET语句
REPLACEINTOusersSETid=123,name=赵本山,age=50;
下面曾提到REPLACE大概影响3条以上的纪录,这是由于在表中有凌驾一个的独一索引。在这类情形下,REPLACE将思索每个独一索引,并对每个索引对应的反复纪录都删除,然后拔出这条新纪录。假定有一个table1表,有3个字段a,b,c。它们都有一个独一索引。
CREATETABLEtable1(aINTNOTNULLUNIQUE,bINTNOTNULLUNIQUE,cINTNOTNULLUNIQUE);
假定table1中已有了3笔记录
abc
111
222
333
上面我们利用REPLACE语句向table1中拔出一笔记录。
REPLACEINTOtable1(a,b,c)VALUES(1,2,3);
前往的了局以下
QueryOK,4rowsaffected(0.00sec)
在table1中的纪录以下
abc
123
我们能够看到,REPLACE将本来的3笔记录都删除,然后将(1,2,3)拔出。
2、UPDATE
UPDATE的功效是更新表中的数据。这的语法和INSERT的第二种用法类似。必需供应表名和SET表达式,在前面能够加WHERE以限定更新的纪录局限。
UPDATEtable_anemSETcolumn_name1=value1,column_name2=value2,...
WHERE...;
以下面的语句将users表中id即是123的纪录的age改成24
UPDATEusersSETage=24WHEREid=123;
一样,可使用UPDATE更新多个字段的值UPDATEusersSETage=24,name=MikeWHEREid=123;
下面的UPDATE语句经由过程WHERE指定一个前提,不然,UPDATE将更新表中的一切纪录的值。
在利用UPDATE更新纪录时,假如被更新的字段的范例和所赋的值不婚配时,MySQL将这个值转换为响应范例的值。假如这个字段是数值范例,并且所赋值凌驾了这个数据范例的最年夜局限,那末MySQL就将这个值转换为这个局限最年夜或最小值。假如字符串太长,MySQL就将过剩的字符串截往。假如设置非空字段为空,那末将这个字段设置为它们的默许值,数字的默许值是0,字符串的默许值是空串(不是null,是"")。
有两种情形UPDATE不会对影响表中的数据。
1.当WHERE中的前提在表中没有纪录和它婚配时。
2.当我们将一样的值赋给某个字段时,如将字段abc赋为123,而abc的原值就是123。
和INSERT、REPLACE一样,UPDATE也前往所更新的纪录数。但这些纪录数其实不包含满意WHERE前提的,但却未被更新的纪录。以下同的UPDATE语句就未更新任何纪录。
UPDATEusersSETage=30WHEREid=12;
QueryOK,0rowsaffected(0.00sec)
必要注重的时,假如一个字段的范例是TIMESTAMP,那末这个字段在别的字段更新时主动更新。
在有些时分我们必要失掉UPDATE所选择的行数,而不是被更新的行数。我们能够经由过程一些API来到达这个目标。如MySQL供应的CAPI供应了一个选项能够失掉你想要的纪录数。而MySQL的JDBC驱动失掉的默许纪录数也是婚配的纪录数。
UPDATE和REPLACE基础相似,可是它们之间有两点分歧。
1.UPDATE在没有婚配纪录时甚么都不做,而REPLACE在有反复纪录时更新,在没有反复纪录时拔出。
2.UPDATE能够选择性地更新纪录的一部分字段。而REPLACE在发明有反复纪录时就将这笔记录完全删除,再拔出新的纪录。也就是说,将一切的字段都更新了。
3、DELETE和TRUNCATETABLE
在MySQL中有两种办法能够删除数据,一种是DELETE语句,另外一种是TRUNCATETABLE语句。DELETE语句能够经由过程WHERE对要删除的纪录举行选择。而利用TRUNCATETABLE将删除表中的一切纪录。因而,DELETE语句更天真。
假如要清空表中的一切纪录,可使用上面的两种办法:
DELETEFROMtable1
TRUNCATETABLEtable1
个中第二笔记录中的TABLE是可选的。
假如要删除表中的部分纪录,只能利用DELETE语句。
DELETEFROMtable1WHERE...;
假如DELETE不加WHERE子句,那末它和TRUNCATETABLE是一样的,但它们有一点分歧,那就是DELETE能够前往被删除的纪录数,而TRUNCATETABLE前往的是0。
假如一个表中有自增字段,利用TRUNCATETABLE和没有WHERE子句的DELETE删除一切纪录后,这个自增字段将肇端值恢复成1.假如你不想如许做的话,能够在DELETE语句中加上永真的WHERE,如WHERE1或WHEREtrue。
DELETEFROMtable1WHERE1;
下面的语句在实行时将扫描每笔记录。但它其实不对照,由于这个WHERE前提永久为true。如许做固然能够坚持自增的最年夜值,但因为它是扫描了一切的纪录,因而,它的实行本钱要比没有WHERE子句的DELETE年夜很多。
DELETE和TRUNCATETABLE的最年夜区分是DELETE能够经由过程WHERE语句选择要删除的纪录。但实行得速率不快。并且还能够前往被删除的纪录数。而TRUNCATETABLE没法删除指定的纪录,并且不克不及前往被删除的纪录。但它实行得十分快。
和尺度的SQL语句分歧,DELETE撑持ORDERBY和LIMIT子句,经由过程这两个子句,我们能够更好地把持要删除的纪录。如当我们只想删除WHERE子句过滤出来的纪录的一部分,可使用LIMIB,假如要删除后几笔记录,能够经由过程ORDERBY和LIMIT共同利用。假定我们要删除users表中name即是"Mike"的前6笔记录。可使用以下的DELETE语句:
DELETEFROMusersWHEREname=MikeLIMIT6;
一样平常MySQL其实不断定删除的这6笔记录是哪6条,为了更保险,我们可使用ORDERBY对纪录举行排序。
DELETEFROMusersWHEREname=MikeORDERBYidDESCLIMIT6;
MySQL的低成本来自于其简单性吗?它的普及性是由于其低成本吗?其实,在MySQL的最“好”与最“不好”的功能之间没有明显的分界线,但它们组合在一起就形成了一副让我们欣赏的作品。

活着的死人 发表于 2015-1-18 18:09:29

至于淘汰的问题,只能说在你的项目周期之内,微软应该都不会倒闭。

变相怪杰 发表于 2015-2-5 12:21:33

SQLServer的异构移植功能个人感觉最好了。(如果对比过SQLServer的链接服务器和Oracle的透明网关的朋友会发现SQLServer的sp_addlinkedserver(openquery)异构数据库系列比Oracle真是强太多了。)

山那边是海 发表于 2015-2-11 20:26:53

这就引发了对varchar和char效率讨论的老问题。到底如何分配varchar的数据,是否会出现大规模的碎片?

因胸联盟 发表于 2015-3-2 18:51:19

分区表是个亮点!从分区表也能看出微软要做大作强SQLServer的信心。资料很多,这里不详细说。但是重点了解的是:现在的SQLServer2005的表,都是默认为分区表的。因为它要支持滑动窗口的这个特性。这种特性对历史数据和实时数据的处理是很有帮助的。

小女巫 发表于 2015-3-17 22:08:24

where子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,条件中不能包含聚组函数,使用where条件显示特定的行。

兰色精灵 发表于 2015-3-25 04:29:24

无法深入到数据库系统层面去了解和探究
页: [1]
查看完整版本: 绝无经由的透视MySQL数据库之更新语句