1、 插入记录
1.1 明确只插入一条Value
INSERT INTO t1(field1,field2) VALUE(v001,v002);
1.2 插入批量数据
INSERT INTO t1(field1,field2) VALUES(v101,v102),(v201,v202),(v301,v302),(v401,v402);
【注】
当 id 为自增,即 id INT PRIMARY KEY AUTO_INCREMENT 时,执行 insert into 语句有两种方式:
1.2.1 含插入列名&含自增id
INSERT INTO t1(id,field1,field2) VALUES(null,v101,v102),(null,v201,v202);
1.2.2 含插入列名&不含自增id
INSERT INTO t1(field1,field2) VALUES(v101,v102),(v201,v202);
1.2.3 不含插入列名&必须含自增id
INSERT INTO t1 VALUES(null,v101,v102),(null,v201,v202);
1.3 指定插入到 talbe2 中的列
INSERT INTO t2(field1,field2) SELECT colm1,colm2 FROM t1 WHERE ……
- 可以通过相对较复杂的查询语句进行数据源获取,插入到 talbe2 中的列;
- 可能使用起来会更加的灵活一些,但我们也必须注意,我们在指定目标表的列时,一定要将所有非空列都填上,否则将无法进行数据插入;
INSERT INTO t2 SELECT colm1,colm2,…… FROM t1
- SELECT 后面的列的顺序 必须和目标表中的列的定义顺序完全一致 才能完成正确的数据插入,这是一个很容易被忽略的地方,值得注意;
1.4 INSERT INTO SET
INSERT INTO 表名 SET 列名1 = 列值1,列名2=列值2,...;
【注】 用INSERT INTO SET这种方式,不能批量增加数据。
2、 更新记录
UPDATE 表名 SET column_name=value [,column_name2=value2,...] [WHEREcondition];
或者理解为:UPDATE 表名 SET 列名=VALUE WHERE [条件]
注意 :
- column_name 为要更改的数据列,尽量带上``
- value 为修改后的数据 , 可以为变量 , 具体指 , 表达式或者嵌套的SELECT结果
- 例如:UPDATE `student` SET `borndate`=CURRENT_TIME WHERE `studentname`='万进进' AND sex='女' CURRENT_TIME为数据库当前时间
- condition 为筛选条件 , 如不指定则修改该表的所有列数据
3、 删除记录
DELETE FROM 表名 [WHERE condition];
注意:condition为筛选条件 , 如不指定则删除该表的所有列数据
- 根据条件删除:DELETE FROM tb_name [WHERE options] [ [ ORDER BY fields ] LIMIT n;
- 全部删除(表清空,包含自增计数器重置):TRUNCATE tb_name;
4、创建一张新表
4.1 直接创建表:
CREATE TABLE
[IF NOT EXISTS] tb_name -- 不存在才创建,存在就跳过
(column_name1 data_type1 -- 列名和类型必选
[ PRIMARY KEY -- 可选的约束,主键
| FOREIGN KEY -- 外键,引用其他表的键值
| AUTO_INCREMENT -- 自增ID
| COMMENT comment -- 列注释(评论)
| DEFAULT default_value -- 默认值
| UNIQUE -- 唯一性约束,不允许两条记录该列值相同
| NOT NULL -- 该列非空
], ...
) [CHARACTER SET charset] -- 字符集编码
[COLLATE collate_value] -- 列排序和比较时的规则(是否区分大小写等)
例:
create table if not exists user_info_vip (
id int(11) primary key auto_increment comment '自增ID',
uid int(11) unique not null comment '用户ID',
nick_name varchar(64) comment '昵称',
achievement int(11) default 0 comment '成就值',
level int(11) comment '用户等级',
job varchar(32) comment '职业方向',
register_time datetime default current_timestamp comment '注册时间'
);
4.2 从另一张表复制表结构创建表
CREATE TABLE tb_name LIKE tb_name_old
4.3 从另一张表的查询结果创建表
CREATE TABLE tb_name AS SELECT * FROM tb_name_old WHERE options
5、 修改表
5.1 增加列在某列之后
alter table 增加的表格 add 增加列的名称 数据类型 位置(after level 在level 之后)
5.2 更换列的名称及数据类型
alter table user_info change 原列名 修改列名 修改数据类型
5.3 更改数据类型
alter table 表名 modify 修改列名称 数据类型 默认值等
{ ADD COLUMN <列名> <类型> -- 增加列
| CHANGE COLUMN <旧列名> <新列名> <新列类型> -- 修改列名或类型
| ALTER COLUMN <列名> { SET DEFAULT <默认值> | DROP DEFAULT } -- 修改/删除 列的默认值
| MODIFY COLUMN <列名> <类型> -- 修改列类型
| DROP COLUMN <列名> -- 删除列
| RENAME TO <新表名> -- 修改表名
| CHARACTER SET <字符集名> -- 修改字符集
| COLLATE <校对规则名> } -- 修改校对规则(比较和排序时用到)
6、 删除表
DROP TABLE [IF EXISTS] 表名1 , [表名2];
IF EXISTS 如果存在才删除
7、 创建索引
7.1 数据库建立索引常用的规则如下:
1、表的主键、外键必须有索引;
2、数据量超过300的表应该有索引;
3、经常与其他表进行连接的表,在连接字段上应该建立索引;
4、经常出现在Where子句中的字段,特别是大表的字段,应该建立索引;
5、索引应该建在选择性高的字段上;
6、索引应该建在小字段上,对于大的文本字段甚至超长字段,不要建索引;
7、复合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替:
A、正确选择复合索引中的主列字段,一般是选择性较好的字段;
B、复合索引的几个字段是否经常同时以AND方式出现在Where子句中?单字段查询是否极少甚至没有?如果是,则可以建立复合索引;否则考虑单字段索引;
C、如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引;
E、如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;
8、频繁进行数据操作的表,不要建立太多的索引;
9、删除无用的索引,避免对执行计划造成负面影响;
以上是一些普遍的建立索引时的判断依据。
索引的建立必须慎重,对每个索引的必要性都应该经过仔细分析,要有建立的依据。
因为太多的索引与不充分、不正确的索引对性能都毫无益处:在表上建立的每个索引都会增加存储开销,索引对于插入、删除、更新操作也会增加处理上的开销。 另外,过多的复合索引,在有单字段索引的情况下,一般都是没有存在价值的;相反,还会降低数据增加删除时的性能,特别是对频繁更新的表来说,负面影响更大。
总的来说,小型表肯定不建索引,
或者数据库记录在亿条数据级以上,还是建议使用非关系型数据库。
还有些特殊字段的数据库,比如BLOB,CLOB字段肯定也不适合建索引。
其实这个问题更感觉偏向于做软件项目的一种经验。
7.2 对千万级MySQL数据库建立索引的事项及提高性能的手段
一、注意事项:
首先,应当考虑表空间和磁盘空间是否足够。我们知道索引也是一种数据,在建立索引的时候势必也会占用大量表空间。因此在对一大表建立索引的时候首先应当考虑的是空间容量问题。
其次,在对建立索引的时候要对表进行加锁,因此应当注意操作在业务空闲的时候进行。
二、性能调整方面:
- 首当其冲的考虑因素便是磁盘I/O。物理上,应当尽量把索引与数据分散到不同的磁盘上(不考虑阵列的情况)。逻辑上,数据表空间与索引表空间分开。这是在建索引时应当遵守的基本准则。
- 其次,我们知道,在建立索引的时候要对表进行全表的扫描工作,因此,应当考虑调大初始化参数db_file_multiblock_read_count的值。一般设置为32或更大。
- 再次,建立索引除了要进行全表扫描外同时还要对数据进行大量的排序操作,因此,应当调整排序区的大小。
- 9i之前,可以在session级别上加大sort_area_size的大小,比如设置为100m或者更大。
- 9i以后,如果初始化参数workarea_size_policy的值为TRUE,则排序区从pga_aggregate_target里自动分配获得。
- 最后,建立索引的时候,可以加上nologging选项。以减少在建立索引过程中产生的大量redo,从而提高执行的速度。
7.3 MySql在建立索引优化时需要注意的问题
设计好MySql的索引可以让你的数据库飞起来,大大的提高数据库效率。设计MySql索引的时候有以下几点注意:
1、创建索引
对于查询占主要的应用来说,索引显得尤为重要。很多时候性能问题很简单的就是因为我们忘了添加索引而造成的,或者说没有添加更为有效的索引导致。如果不加索引的话,那么查找任何哪怕只是一条特定的数据都会进行一次全表扫描,如果一张表的数据量很大而符合条件的结果又很少,那么不加索引会引起致命的性能下降。但是也不是什么情况都非得建索引不可,比如性别可能就只有两个值,建索引不仅没什么优势,还会影响到更新速度,这被称为过度索引。
2、复合索引
比如有一条语句是这样的:select * from users where area=’beijing’ and age=22;
如果我们是在area和age上分别创建单个索引的话,由于mysql查询每次只能使用一个索引,所以虽然这样已经相对不做索引时全表扫描提高了很多效 率,但是如果在area、age两列上创建复合索引的话将带来更高的效率。如果我们创建了(area, age, salary)的复合索引,那么其实相当于创建了(area,age,salary)、(area,age)、(area)三个索引,这被称为最佳左前缀
特性。因此我们在创建复合索引时应该将最常用作限制条件的列放在最左边,依次递减。
3、索引不会包含有NULL值的列
只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。
4、使用短索引
对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的 列,如果在前10 个或20 个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。
5、排序的索引问题
mysql查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。
6、like语句操作
一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%a%” 不会使用索引而like “aaa%”可以使用索引。
7、不要在列上进行运算
select * from users where YEAR(adddate)
8、不使用NOT IN和操作
NOT IN操作不会使用索引将进行全表扫描。NOT IN可以NOT EXISTS代替;
7.4 添加索引示例:
CREATE INDEX IDX_AUDITSTATUS ON [shanghaiDB].[dbo].[Activity](AUDITSTATUS) WITH(ONLINE=ON)
CREATE INDEX IDX_ANUMMID ON [nantongDB].[dbo].[Orders](ANUM,MID) WITH(ONLINE=ON)
CREATE INDEX IDX_SiteCode ON Usercenter.[dbo].MO(SiteCode) WITH(ONLINE=ON)
CREATE INDEX IDX_AccessDt ON [all].[dbo].[AccessLog](AccessDt) WITH(ONLINE=ON)
Create index注意n如果是大表建立索引,切记加上ONLINE参数
这几天在做数据库的优化,有个2亿记录的表,发现需要添加一个联合索引,结果就采用普通的create index index_name on tablename (entp_id,sell_date),结果悲剧了,把所有的DML语句都阻塞了,导致系统不能正常使用,还好是晚上10点,用户不是非常多,1个小时候,索引结束,阻塞解决;
-
DML操作对create index 的影响。 如果在create的时候,有其他的进程在对这个index 所对应的数据进行DML操作,create会受影响:
-
加online这个参数,这个参数加上以后,除了create过程中index 保持online状态,Oracle还会在create index之前等待所有DML操作结束,然后得到DDL锁,开始create.
7.5 Mysql 索引类型以及创建
关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车。对于没有索引的表,单表查询可能几十万数据就是瓶颈,而通常大型网站单日就可能会产生几十万甚至几百万的数据,没有索引查询会变的非常缓慢。还是以WordPress来说,其多个数据表都会对经常被查询的字段添加索引,比如wp_comments表中针对5个字段设计了BTREE索引。
7.6 MySQL索引的概念
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。更通俗的说,数据库索引好比是一本书前面的目录,能加快数据库的查询速度。上述SQL语句,在没有索引的情况下,数据库会遍历全部200条数据后选择符合条件的;而有了相应的索引之后,数据库会直接在索引中查找符合条件的选项。如果我们把SQL语句换成“SELECT * FROM article WHERE id=2000000”,那么你是希望数据库按照顺序读取完200万行数据以后给你结果还是直接在索引中定位呢?(注:一般数据库默认都会为主键生成索引)。
索引分为聚簇索引和非聚簇索引两种,聚簇索引是按照数据存放的物理位置为顺序的,而非聚簇索引就不一样了;聚簇索引能提高多行检索的速度,而非聚簇索引对于单行的检索很快。 MySQL索引的类型
1. 普通索引
ALTER TABLE article ADD INDEX index_article_title ON title(200);
这是最基本的索引,它没有任何限制,比如为title字段创建的索引就是一个普通索引,MyIASM中默认的BTREE类型的索引,也是我们大多数情况下用到的索引。
直接创建索引
CREATE INDEX index_name ON table(column(length))
修改表结构的方式添加索引
ALTER TABLE table_name ADD INDEX index_name ON (column(length))
创建表的时候同时创建索引
CREATE TABLE `table` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`time` int(10) NULL DEFAULT NULL ,
PRIMARY KEY (`id`),
INDEX index_name (title(length))
)
删除索引
DROP INDEX index_name ON table
2. 唯一索引
与普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值(注意和主键不同)。如果是组合索引,则列值的组合必须唯一,创建方法和普通索引类似。
#创建唯一索引
CREATE UNIQUE INDEX indexName ON TABLE(COLUMN(LENGTH))
#修改表结构
ALTER TABLE table_name ADD UNIQUE indexName ON (COLUMN(LENGTH))
#创建表的时候直接指定
CREATE TABLE `table` (
`id` INT(11) NOT NULL AUTO_INCREMENT ,
`title` CHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`content` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`time` INT(10) NULL DEFAULT NULL ,
PRIMARY KEY (`id`),
UNIQUE indexName (title(LENGTH))
)
3. 全文索引(FULLTEXT)
MySQL从3.23.23版开始支持全文索引和全文检索,FULLTEXT索引仅可用于 MyISAM 表;他们可以从CHAR、VARCHAR或TEXT列中作为CREATE TABLE语句的一部分被创建,或是随后使用ALTER TABLE 或CREATE INDEX被添加。对于较大的数据集,将你的资料输入一个没有FULLTEXT索引的表中,然后创建索引,其速度比把资料输入现有FULLTEXT索引的速度更为快。不过切记对于大容量的数据表,生成全文索引是一个非常消耗时间非常消耗硬盘空间的做法。
创建表的适合添加全文索引
CREATE TABLE `table` (
`id` int(11) NOT NULL AUTO_INCREMENT ,
`title` char(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
`content` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL ,
`time` int(10) NULL DEFAULT NULL ,
PRIMARY KEY (`id`),
FULLTEXT INDEX index_name (column)
)
修改表结构添加全文索引
ALTER TABLE article ADD FULLTEXT INDEX index_name (column)
直接创建索引
CREATE FULLTEXT INDEX index_name ON article(column)
4. 单列索引、多列索引
多个单列索引与单个多列索引的查询效果不同,因为执行查询时,MySQL只能使用一个索引,会从多个索引中选择一个限制最为严格的索引。
5. 组合索引(最左前缀)
平时用的SQL查询语句一般都有比较多的限制条件,所以为了进一步榨取MySQL的效率,就要考虑建立组合索引。例如上表中针对title和time建立一个组合索引:ALTER TABLE article ADD INDEX index_titme_time (title(50),time(10))。建立这样的组合索引,其实是相当于分别建立了下面两组组合索引:(title,time),title,为什么没有time这样的组合索引呢?这是因为MySQL组合索引“最左前缀”的结果。简单的理解就是只从最左面的开始组合。并不是只要包含这两列的查询都会用到该组合索引,如下面的几个SQL所示:
使用到上面的索引
SELECT * FROM article WHREE title='测试' AND time=1234567890;
SELECT * FROM article WHREE utitle='测试';
不使用上面的索引
SELECT * FROM article WHREE time=1234567890;
MySQL索引的优化
上面都在说使用索引的好处,但过多的使用索引将会造成滥用。因此索引也会有它的缺点:虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE。因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件。建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会膨胀很快。索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立最优秀的索引,或优化查询语句。下面是一些总结以及收藏的MySQL索引的注意事项和优化方法。
7.7 创建索引
-
在duration列创建普通索引idx_duration、
-
在exam_id列创建唯一性索引uniq_idx_exam_id、
-
在tag列创建全文索引full_idx_tag。
-- 唯一索引
ALTER TABLE examination_info
ADD UNIQUE INDEX uniq_idx_exam_id(exam_id);
-- 全文索引
ALTER TABLE examination_info
ADD FULLTEXT INDEX full_idx_tag(tag);
-- 普通索引
ALTER TABLE examination_info
ADD INDEX idx_duration(duration);