mysql 常用dml 语句

三世轮回 提交于 2019-12-05 11:39:32

最近在准备给公司的研发培训一点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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!