最近在准备给公司的研发培训一点mysql 知识,其实我也懂的不是太多,只能自己先学点,然后在去给他们讲,下面是自己整理的一些东西
3.1 建表
存储引擎说白了就是如何存储数据、如何为存储的数据建立索引和如何更新、查询数据等技术的实现方法。因为在关系数据库中数据的存储是以表的形式存储的,所以存储引擎也可以称为表类型(即存储和操作此表的类型)
在Oracle 和SQL Server等数据库中只有一种存储引擎,所有数据存储管理机制都是一样的。而MySql数据库提供了多种存储引擎。用户可以根据不同的需求为数据表选择不同的存储引擎,用户也可以根据自己的需要编写自己的存储引擎。
3.1.1 mysql存储引擎
MyISAM存储引擎是Mysql中常见的存储引擎,MyISAM存储引擎是基于ISAM存储引擎发展起来的。MyISAM支持全文索引、压缩存放、空间索引(空间函数)、表级锁、延迟更新索引键。但是MyISAM不支持事务、行级锁、更无法忍受的是崩溃后不能保证完全恢复(只能手动修复)
InnoDB:InnoDB表类型可以看作是对MyISAM的进一步更新产品,nnoDB是Mysql数据库的一种存储引擎。InnoDB给Mysql的表提供了 事务、回滚、崩溃修复能力、多版本并发控制的事务安全、间隙锁(可以有效的防止幻读的出现)、支持辅助索引、聚簇索引、自适应hash索引、支持热备、行级锁。还有InnoDB是Mysql上唯一一个提供了外键约束的引擎
memory(heap):这种类型的数据表只存在于内存中。它使用散列索引,所以数据
的存取速度非常快。因为是存在于内存中,所以这种类型常应用于临时表中。
archive:这种类型只支持select 和 insert语句,而且不支持索引。常应用于日志记录和聚合分析方面。
但是在生产中我们常用的还是myisam,innodb 存储引擎。
3.1.2MYSQL 表命名规则
MySQL在Linux下数据库名、表名、列名、别名大小写规则是这样的:
1、数据库名与表名是严格区分大小写的;
2、表的别名是严格区分大小写的;
3、列名与列的别名在所有的情况下均是忽略大小写的;
4、变量名也是严格区分大小写的;
CREATE TABLE engineTest(
id INT
) ENGINE = MyISAM; // 用engine 来指定我们要创建那种类型的表
对于存储引擎的选择对char和varchar 使用有不用的原则:
Myisam 建立使用固定长度的数据列来代替使用可变长度的列
Innodb 建立使用varchar类型
主键自增:
CREATE TABLE test
(
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(15) NOT NULL
)AUTO_INCREMENT = 100;
可在建表时可用“AUTO_INCREMENT=n”选项来指定一个自增的初始值。
alter table tbname auto_increment = x ;
设置表tbname的唯一auto_increment字段起始值从x开始,如果此表数据量很多的话,这样执行起来会很慢
AUTO_INCREMENT说明:
(1)如果把一个NULL插入到一个AUTO_INCREMENT数据列里去,MySQL将自动生成下一个序列编号。编号从1开始,并1为基数递增。
(2)把0插入AUTO_INCREMENT数据列的效果与插入NULL值一样。但不建议这样做,还是以插入NULL值为好。
(3)当插入记录时,没有为AUTO_INCREMENT明确指定值,则等同插入NULL值。
(4)当插入记录时,如果为AUTO_INCREMENT数据列明确指定了一个数值,则会出现两种情况,情况一,如果插入的值与已有的编号重复,则会出现出错信息,因为AUTO_INCREMENT数据列的值必须是唯一的;情况二,如果插入的值大于已编号的值,则会把该插入到数据列中,并使在下一个编号将从这个新值开始递增。也就是说,可以跳过一些编号。
(5)如果用UPDATE命令更新自增列,如果列值与已有的值重复,则会出错。如果大于已有值,则下一个编号从该值开始递增。
mysql> insert into testvalues(1,'a'),(2,'b'),(null,'c');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * From test;
+-----+----------+
| id | username |
+-----+----------+
| 1| a |
| 2| b |
| 100 | c |
+-----+----------+
3 rows in set (0.00 sec)
修改某一列为自增:
mysql> alter table test change id id int AUTO_INCREMENT;
mysql> create table t24(id int,namechar(10));
mysql> alter table t24 add primarykey(id); //添加主键
mysql> alter table t24 modify id intauto_increment;//加入自动增加
/**删除主键唯一约束,还原到建表时的状态*/
mysql> alter table t24 modify id int; //去掉auto_increment
mysql> alter table t24 drop primary key;
mysql> alter table t24 modify id int;//修改默认值为null
/**删除唯一索引约束,还原到建表时的状态*/
mysql> alter table t24 modify id intunique;//增加唯一约束
mysql> show create table t24;
CREATE TABLE `t24` (
`id` int(11) DEFAULT NULL,
`name` char(10) DEFAULT NULL,
UNIQUE KEY `id` (`id`)
) ENGINE=MyISAM DEFAULTCHARSET=latin1
mysql> alter table t24 drop index id; //删除唯一索引
mysql> show engines\G //查看MySql有哪些搜索引擎
mysql> show create table t2 \G; //查看表的创建
*************************** 1. row***************************
Table: t2
Create Table: CREATE TABLE `t2` (
`a`char(4) DEFAULT NULL,
`b`varchar(4) DEFAULT NULL,
KEY`i_t2` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
3.2建索引
给表t2创建索引
mysql> show index from t2;
Empty set (0.00 sec)
mysql> alter table t2 add index i_t2(a);
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from t2; //查看t2所有所索引
*************************** 1. row***************************
Table: t2
Non_unique: 1
Key_name: i_t2
Seq_in_index: 1
Column_name: a
Collation: A
Cardinality: 1
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
1 row in set (0.00 sec)1 row in set (0.00sec)
3.3 索引的设计和使用
1、索引搜索的列,最好是where条件中的列或者连接子句中指定的列
2、使用唯一索引
3、使用短索引,如果是对字符串列进行索引,可以指定一个前缀的长度,如果能够在10-20个字符能够多数值唯一行,那么就不要对整个索引列进行索引。因为较小的索引io比较少较短的值比较起来更快。
Create index cityname on city(city(10));
4、如果要使用like 通配符最后在后面 如 like ‘city%’
3.4视图
视图是从一个或多个表中导出来的表,是一种虚拟存在的表。
视图就像一个窗口,通过这个窗口可以看到系统专门提供的数据。
这样,用户可以不用看到整个数据库中的数据,而之关心对自己有用的数据。
数据库中只存放了视图的定义,而没有存放视图中的数据,这些数据存放在原来的表中。
CREATE[ALGORITHM]={UNDEFINED|MERGE|TEMPTABLE}]
VIEW 视图名 [(属性清单)]
AS SELECT 语句
[WITH [CASCADED|LOCAL] CHECK OPTION];
l ALGORITHM表示视图选择的算法(可选参数)
UNDEFINED:MySQL将自动选择所要使用的算法
MERGE:将视图的语句与视图定义合并起来,使得视图定义的某一部分取代语句的对应部分
TEMPTABLE:将视图的结果存入临时表,然后使用临时表执行语句
视图名表示要创建的视图的名称,属性清单表示视图中的列名,默认与SELECT查询结果中的列名相同(可选参数)
l WITH CHECK OPTION表示更新视图时要保证在该试图的权限范围之内(可选参数)
CASCADED:更新视图时要满足所有相关视图和表的条件
LOCAL:更新视图时,要满足该视图本身定义的条件即可
tips:创建试图时最好加上WITHCASCADED CHECK OPTION参数,这种方式比较严格
可以保证数据的安全性
mysql> select * from t1;
+------+-------+------------+
| a | b | c |
+------+-------+------------+
| 127 | 32767 | 123456 |
| 127 | 32767 | 1234567890 |
+------+-------+------------+
2 rows in set (0.00 sec)
mysql> CREATE VIEW t1_view(ID,NAME) ASSELECT a,c FROM t1;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from t1_view;
+------+------------+
| ID | NAME |
+------+------------+
| 127 | 123456 |
| 127 | 1234567890 |
+------+------------+
2 rows in set (0.00 sec)
查看视图定义:
mysql> show create view t1_view \G;
*************************** 1. row***************************
View: t1_view
Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQLSECURITY DEFINER VIEW `t1_view` AS select `t1`.`a` AS `ID`,`t1`.`c` AS `NAME`from `t1`
character_set_client: utf8
collation_connection: utf8_general_ci
1 row in set (0.00 sec)
mysql> SELECT * FROMinformation_schema.views\G;
*************************** 1. row***************************
TABLE_CATALOG: def
TABLE_SCHEMA: test
TABLE_NAME: t1_view
VIEW_DEFINITION: select `test`.`t1`.`a` AS `ID`,`test`.`t1`.`c` AS`NAME` from `test`.`t1`
CHECK_OPTION: NONE
IS_UPDATABLE: YES
DEFINER: root@localhost
SECURITY_TYPE: DEFINER
CHARACTER_SET_CLIENT: utf8
COLLATION_CONNECTION: utf8_general_ci
1 row in set (0.07 sec)
更新视图:
UPDATE salary_view SET salary=5899.00 WHERE id=1;
tips:视图中虽然可以更新数据,但是有很多限制
一般情况下,最好将视图作为查询数据的虚拟表,而不要通过视图更新数据
多表关联试图:
CREATE ALGORITHM=MERGE VIEW work_view(ID,NAME,SALARY)
AS SELECT work.id,name,salary FROM work,salary
WHERE work.id=salary.id
WITH LOCAL CHECK OPTION;
删除视图:
删除视图是指删除数据库中已存在的视图,删除视图时,只能删除视图的定义,不会删除数据
DROP VIEW IF EXISTS t1_view;
3.5常用dml 语句
3.5.1Insert数据:
一次insert 插入多条数据
mysql> insert into test1values(1,'a'),(2,'b'),(null,'c');
Ignore:插入数据时忽略重复的数据
mysql> select * From test;
+-----+----------+
| id | username |
+-----+----------+
| 1| a |
| 2| b |
| 100 | c |
+-----+----------+
3 rows in set (0.00 sec)
mysql> insert ignore into test select *From test;
Query OK, 0 rows affected, 2 warnings (0.00sec)
Records: 3 Duplicates: 3 Warnings: 2
mysql> select * from test;
+-----+----------+
| id | username |
+-----+----------+
| 1| a |
| 2| b |
| 100 | c |
+-----+----------+
3 rows in set (0.00 sec)
插入时遇到重复记录做更新操作
还有一个表test,与表test1的结构类似,现需将表test中的数据插入test1中,当遇到重复的记录时,更新username这一列为表test中的值
mysql> select * From test;
+----+----------+
| id | username |
+----+----------+
| 1| a |
| 2| b |
| 3| c |
+----+----------+
3 rows in set (0.00 sec)
mysql> select * from test1;
+----+----------+
| id | username |
+----+----------+
| 1| hh |
| 2| hh |
| 3| hh |
| 4| aa |
+----+----------+
4 rows in set (0.00 sec)
mysql> insert into test1 (id,username)select id,username from test on duplicate key updatetest1.username=test.username;
Query OK, 6 rows affected, 2 warnings (0.02sec)
Records: 3 Duplicates: 3 Warnings: 2
mysql> select * From test;
+----+----------+
| id | username |
+----+----------+
| 1| a |
| 2| b |
| 3| c |
+----+----------+
3 rows in set (0.00 sec)
mysql> select * From test1;
+----+----------+
| id | username |
+----+----------+
| 1| a |
| 2| b |
| 3| c |
| 4| aa |
+----+----------+
4 rows in set (0.00 sec)
3.5.2排序:
mysql> select * From test order by iddesc;
+-----+----------+
| id | username |
+-----+----------+
| 100 | c |
| 2| b |
| 1| a |
+-----+----------+
3 rows in set (0.00 sec)
3.5.3获取前两行数据:
LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是 0(而不是 1),
LIMIT n 等价于 LIMIT 0,n。
SELECT * FROM table LIMIT[offset,] rows
SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15
mysql> select * From test order by iddesc limit 2;
+-----+----------+
| id | username |
+-----+----------+
| 100 | c |
| 2| b |
+-----+----------+
2 rows in set (0.00 sec)
---偏移量,从第二条数据开始,获取2条数据
mysql> select * From test1 order by id limit 2,2;
+----+----------+
| id | username |
+----+----------+
| 3| c |
| 4| aa |
+----+----------+
2 rows in set (0.00 sec)
偏移offset较小的时候,直接使用limit较优。这个显示是子查询的原因
偏移offset大的时候,使用limitoffset,rows
来源:CSDN
作者:wluckdog
链接:https://blog.csdn.net/wll_1017/article/details/44960237