zoukankan      html  css  js  c++  java
  • MariaDB数据库(四)

    1. 数据库备份与恢复

      数据库备份用命令mysqldump ,MySQL的备份文件一般以.sql结尾,做到见名知意

    #备份testdb数据库重定向为testdb.sql文件,
    [root@localhost ~]# mysqldump -uroot -p123 --databases testdb > testdb.sql
    
    #备份所有的数据库
    [root@localhost ~]# mysqldump -uroot -p123 --all-databases > all_databases.sql
     
    #查看备份的文件
    [root@localhost ~]# ls
    all_databases.sql     testdb.sql
    [root@localhost ~]#vimttestdb.mysql
    ………
    CREATE DATABASE /*!32312 IF NOT EXISTS*/ `testdb` /*!40100 DEFAULT CHARACTER SET utf8 */;
     
    USE `testdb`;
    
    --
    -- Table structure for table `areas`
    --
     
    DROP TABLE IF EXISTS `areas`;
    /*!40101 SET @saved_cs_client     = @@character_set_client */;
    /*!40101 SET character_set_client = utf8 */;
    CREATE TABLE `areas` (
      `aid` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(20) DEFAULT NULL,
      `pid` int(11) DEFAULT NULL,
      PRIMARY KEY (`aid`)
    ) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;
    /*!40101 SET character_set_client = @saved_cs_client */;
     
    --
    -- Dumping data for table `areas`
    --
    
    LOCK TABLES `areas` WRITE;
    /*!40000 ALTER TABLE `areas` DISABLE KEYS */;
    INSERT INTO `areas` VALUES (1,'北京市',NULL),(2,'天津市',NULL),(3,'河北省',NULL),(4,'山西省
    ',NULL),(5,'海淀区',1),(6,'滨海区',2),(7,'沧州市',3),(8,'大同市',4),(9,'朝阳区',1),(10,'武>清区',2),(11,'石家庄',3),(12,'太原市',4),(13,'西二旗',5),(14,'大港',6),(15,'任丘市',7),(16,'清徐',8),(17,'中关村',5),(18,'汉沽',6),(19,'河间市',7),(20,'阳曲',8);
    /*!40000 ALTER TABLE `areas` ENABLE KEYS */;
    UNLOCK TABLES;
    ……..
    
    #恢复用命令source
    MariaDB [(none)]> drop database testdb;
    Query OK, 3 rows affected (0.082 sec)
    MariaDB [(none)]> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    +--------------------+
    3 rows in set (0.000 sec)
    MariaDB [(none)]> source testdb.sql     #导入备份文件
    Query OK, 0 rows affected (0.001 sec)
    Query OK, 0 rows affected (0.000 sec)
    Query OK, 0 rows affected (0.000 sec)
    …….
    MariaDB [testdb]> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | testdb             |
    +--------------------+
    
    #备份数据库下的某个表,先跟数据库名,再跟表名,如备份testdb下的students表:
    MariaDB [testdb]> exit
    Bye
    [root@localhost ~]# mysqldump -uroot -proot testdb students > students.sql
    [root@localhost ~]# ls
    all_databases.sql   students.sql   testdb.sql    #库名后跟的表名可以是多个,以空格分开,即备份同一数据库下的多个表
    [root@localhost ~]# mysqldump -uroot -p123 testdb students classes areas > bak.sql
    [root@localhost ~]# ls
    all_databases.sql   students.sql   testdb.sql   bak.sql

    2. 视图

      对于复杂的查询,在多个地方被使用,如果需求发生了改变,需要更改sql语句,则需要在多个地方进行修改,维护起来非常麻烦,

      假如因为业务需要将某一表拆分为另外两份表,相对来说原来的表没有了,如果要继续使用该表有两种方案:找前端人员要求每个前端人员将他们相关的调用语句修改了,第二种方法是通过某种方法使得查看原来的表时让它“存在”,此时的表并不是真正的表,而是视图。当然,利用视图的方法更好。

    2.1 创建视图

      格式: create view 视图名称 as select语句;

      视图与表的效果相近,因此在创建视图的名称是一般以v_开头表名是视图文件。

      创建视图所含的表如果有相同的字段名必须在创建过程中起别名,使得新创建的一个“表”仅有一个相同的字段,如下列所示。

    MariaDB [testdb]> create view v_students as select * from classes inner join students where classes.id=students.cls_id;
    ERROR 1060 (42S21): Duplicate column name 'id'           #重复的id列名
    MariaDB [testdb]> create view v_students as select classes.name as cl_name,students.name as stu_name from classes inner join students where classes.id=students.cls_id;
    MariaDB [testdb]> show tables;
    +------------------+
    | Tables_in_testdb |
    +------------------+
    | areas            |
    | classes          |
    | students         |
    | v_students       |
    +------------------+

    2.2  查看视图

      格式:show tables ,查看表会将所有的视图也列出来

    MariaDB [testdb]> select * from v_students order by cl_name;
    #查看将两个表联系起来的一个“表”,即视图
    +-------------+-------------+
    | cl_name     | stu_name    |
    +-------------+-------------+
    | 云唯_01期    | 周杰伦儿     |
    | 云唯_01期    | 钱小豪       |
    | 云唯_01期    | 陈冠希       |
    | 云唯_01期    | 小明         |
    | 云唯_01期    | 彭于晏       |
    | 云唯_01期    | 黄蓉         |
    | 云唯_01期    | 王祖贤       |
    | 云唯_01期    | 周杰         |
    | 云唯_01期    | 谢霆锋       |
    | 云唯_02期    | 小月月       |
    | 云唯_02期    | 刘德华       |
    | 云唯_02期    | 凤姐         |
    | 云唯_02期    | 和珅         |
    | 云唯_02期    | 程坤         |
    +-------------+--------------+

    2.3 删除视图

      格式:drop view 视图名

    MariaDB [testdb]> drop view v_students;
    Query OK, 0 rows affected (0.000 sec)
    MariaDB [testdb]> show tables;
    +---------------------+
    | Tables_in_testdb    |
    +---------------------+
    | areas               |
    | classes             |
    | students            |
    +---------------------+

    3. 事务

      假设A欠了B 500 元,A现在给B还钱,对数据库而言,还钱有三个步骤:

        1、检查A的账户余额>500元;

        2、A 账户中扣除500元;

        3、B 账户中增加500元。

      如果A现已将前从自己的账户中扣除,在B还没有收到数据库的数据时数据库宕了,会出现A已经将钱从自己账户扣除、B的账户并没有增加的现象。

      但现实中对数据库来说这种情况是不存在的,因为数据库存在事务这个概念。

      将上述步骤的操作打包成一个事务中,任何一个步骤失败,则必须回滚所有步骤。

           数据库中事务默认是关闭的,使用start transaction或begin开启一个事务,完成操作后使用commit命令提交修改或使用rollback撤销所有修改。

    3.1  事务的ACID特性

       1)原子性(A,atomicity):事务内的所有操作要么都执行,要么都不执行,视所有操作步骤为一个整体,它是一个不可分割的工作单位。一个执行步骤失败,全部步骤失败,全部步骤成功任务才成功。

        2)一致性(C,consistency):数据库的前后一致,数据库总是从一个一致性的状态转换到另一个一致性的状态。

        3)隔离性(I,isolation):一个事物所做的修改在最终提交之前,对其他事物是不可见的。

        4)持久性(D,durability):将数据写入磁盘当中实现永久保存。事务完成后,该事务内涉及的数据必须持久性的写入磁盘保证其持久性。当然,这是从事务的角度来考虑的的持久性,从操作系统故障或硬件故障来说,这是不一定的。

    3.2  事务命令

      要求:表的引擎类型必须是innodb类型才可以使用事务,这是mysql表的默认引擎。

      查看表的创建语句,可以看到engine=innodb。 

      命令:

             show create table students;

      修改数据的命令会触发事务,包括insert、update、delete

      开启事务:begin,开启事务后执行修改命令,变更会维护到本地缓存中,而不维护到物理表中。

      提交事务:commit,将缓存中的数据变更维护到物理表中。

      回滚事务:rollback,放弃缓存中变更的数据。

      结束事务:commit和rollback均可结束事务。

    #为了体现隔离性,开启两个窗口1和2
    #窗口1:
    MariaDB [testdb]> select * from students;
    +---+---------------+------+--------+--------+-------+-----------+
    | id | name         | age  | high   | gender |cls_id | is_delete |
    +----+--------------+------+--------+-------+--------+-----------+
    |  1 | 小明         |   18 | 180.00 | 男     |      1 |           |
    |  2 | 小月月       |   19 | 180.00 | 男     |      2 |           |
    |  3 | 彭于晏       |   28 | 185.00 | 男     |      1 |           |
    |  4 | 刘德华       |   58 | 175.00 | 男     |      2 |           |
    |  5 | 黄蓉         |  108 | 160.00 | 女     |      1 |           |
    |  6 | 凤姐         |   44 | 150.00 | 保密   |      2 |           |
    |  7 | 王祖贤       |   52 | 170.00 | 女     |      1 |           |
    |  8 | 周杰伦儿     |   34 | NULL   | 男     |      1 |           |
    |  9 | 程坤         |   44 | 181.00 | 男     |      2 |           |
    | 10 | 和珅         |   55 | 166.00 | 男     |      2 |           |
    | 11 | 刘亦菲       |   29 | 162.00 | 女     |      3 |           |
    | 12 | 金星         |   45 | 180.00 | 中性   |      4 |           |
    | 13 | 静香         |   18 | 170.00 | 女     |      4 |           |
    | 14 | 郭靖         |   22 | 167.00 | 男     |      5 |           |
    | 15 | 周杰         |   33 | 178.00 | 男     |      1 |           |
    | 16 | 钱小豪       |   56 | 178.00 | 男     |      1 |           |
    | 17 | 谢霆锋       |   38 | 175.00 | 男     |      1 |           |
    | 18 | 陈冠希       |   38 | 175.00 | 男     |      1 |           |
    +----+-------------+------+--------+--------+--- ----+-----------+
    MariaDB [testdb]> begin;                              #开启事务
    MariaDB [testdb]> delete from students where id=17;
    MariaDB [testdb]> delete from students where id=18;    #删除两条数据
    MariaDB [testdb]> select * from students;
    ………
    | 15 | 周杰         |   33 | 178.00 | 男     |      1 |           |
    | 16 | 钱小豪       |   56 | 178.00 | 男     |      1 |           |
    +----+-------------+------+--------+--------+--------+-----------+
    
    #窗口2:
    MariaDB [testdb]> select * from students;
    …….
    | 16 | 钱小豪       |   56 | 178.00 | 男     |      1 |           |
    | 17 | 谢霆锋       |   38 | 175.00 | 男     |      1 |           |
    | 18 | 陈冠希       |   38 | 175.00 | 男     |      1 |           |
    +-- -+-------------+------+--------+--------+--------+-----------+
    #此时窗口1并没有提交(commit),切换到窗口2查看students表,发现并没有删掉该该两条数据,这便是事务的隔离性,一个事务最终修改在提交之前对其他事务是不可见的。
     
    #窗口1:
    MariaDB [testdb]> commit;                             #提交
    #窗口2:  
    MariaDB [testdb]> select * from students;
    ………
    | 15 | 周杰         |   33 | 178.00 | 男     |      1 |           |
    | 16 | 钱小豪       |   56 | 178.00 | 男     |      1 |           |
    +---+--------------+------+--------+--------+--------+-----------+
    MariaDB [testdb]> begin;                              #开启事务
    Query OK, 0 rows affected (0.000 sec)
    MariaDB [testdb]> delete from students where id=15;   #删掉一行数据
    Query OK, 1 row affected (0.002 sec)
    MariaDB [testdb]> select * from students;
    …….
    | 14 | 郭靖         |   22 | 167.00 | 男     |      5 |           |
    +---+--------------+------+--------+--------+--------+-----------+
    MariaDB [testdb]> rollback;                           #回退,后结束事务
    Query OK, 0 rows affected (0.000 sec)
    MariaDB [testdb]> select * from students;
    …….
    | 15 | 周杰         |   33 | 178.00 | 男     |      1 |           |
    +---+--------------+------+--------+--------+--------+-----------+
    
    #事务之中一个步骤出错,所有步骤出错:
    MariaDB [testdb]> begin;
    Query OK, 0 rows affected (0.000 sec)
    MariaDB [testdb]> delete from students where id=13;
    Query OK, 1 row affected (0.000 sec)
    MariaDB [testdb]> delete from students where id=14;      #执行两个步骤
    Query OK, 0 rows affected (0.000 sec)
    MariaDB [testdb]> select * from students;
    …….
    | 12 | 金星         |   45 | 180.00 | 中性   |      4 |           |
    +---+--------------+------+--------+--------+--------+-----------+
    #在没有结束事务之前结束任务,前面执行的两个步骤都是失败的:
    MariaDB [testdb]> exit
    Bye
    [root@localhost ~]# mysql -uroot -p123;
    MariaDB [(none)]> use testdb;
    MariaDB [testdb]> select * from students;
    | 13 | 静香         |   18 | 170.00 | 女     |      4 |           |
    | 14 | 郭靖         |   22 | 167.00 | 男     |      5 |           |
    +---+--------------+------+---------+-------+--------+-----------+
    #注意: truncate执行命令是对硬盘数据进行删除,无法回滚

    MariaDB端口:3306。

    4. 索引

      索引主要用于快速查询。但如果遇到增删改,索引又变得鸡肋。主键默认有索引的功能,因此不必为主键创建索引

    4.1 创建索引

      方式1:创建表时创建索引,如:

    MariaDB [testdb]> create table create_index(
        -> id int primary key,
        -> name varchar(10) unique,
        -> age int,
        -> key (age)
        -> );

     

      方式2:对于已创建的表,添加索引

      如果指定字段是字符串,需要指定长度,建议长度与定义字段时的长度一致;

      字段类型如果不是字符串,可以不填写长度部分

      格式:create index 索引名称 on 表名(字段名称(长度)),如

        create index age_index on create_index(age);

    4.2  查看索引

    MariaDB [testdb]> show create table create_index;
    ……..
    | create_index | CREATE TABLE `create_index` (
      `id` int(11) NOT NULL,
      `name` varchar(10) DEFAULT NULL,
      `age` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `name` (`name`),
      KEY `age` (`age`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
    ……….

    4.3 删除索引

      格式: drop index 索引名称 on 表名;

    MariaDB [testdb]> drop index age on create_index;
    MariaDB [testdb]> show create table create_index;
    ……..
    | create_index | CREATE TABLE `create_index` (
      `id` int(11) NOT NULL,
      `name` varchar(10) DEFAULT NULL,
      `age` int(11) DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `name` (`name`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

     

    4.4 测试时间

           打开sql语句执行时间:set profiling=1

      关闭sql语句执行时间:set profiling=0

      查看sql执行时间:show profiles

    5. 外键

    5.1 概述

      外键是一种约束。如果一个实体的某个字段指向另一个实体的主键,就称为外键。被指向的实体,称之为主实体(主表),也叫父实体(父表)。负责指向的实体,称之为从实体(从表),也叫子实体(子表)

      对关系字段进行约束,当为从表中的关系字段填写值时,会到关联的主表中查询此值是否存在,如果存在则填写成功,如果不存在则填写失败并报错。

    5.2  查看外键

           show create tables 表名

    5.3 添加外键

           如:alter table students add constraint fk_students_gid foreign key (gid) references grade(gid) on delete cascade;    on deleate cascade 允许级联删除

    #给students的cls_id设置外键fkey,参考classes表的id
    MariaDB [testdb]> alter table students add constraint fkey foreign key (cls_id) references classes(id);
    ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`testdb`.`#sql-50a_d`, CONSTRAINT `fkey` FOREIGN KEY (`cls_id`) REFERENCES `classes` (`id`))
    #此处报错并不是语法错误,而是因为students.csl_id有1、2、3、4、5,而classes.id只有1、2,无法一一对应,为完成实验,删除students.csl_id为3、4、5的数据
    MariaDB [testdb]> delete from students where cls_id>2;
    Query OK, 4 rows affected (0.001 sec)
    MariaDB [testdb]> alter table students add constraint fkey foreign key (cls_id) references classes(id);
    Query OK, 10 rows affected (0.046 sec)             
    Records: 10  Duplicates: 0  Warnings: 0
    #测试外键:外键对应id只有1、2,因此无法插入cls_id 为大于2的数据
    MariaDB [testdb]> insert into students values (0,'小明',18,180.2,2,2,0);
    Query OK, 1 row affected (0.001 sec)
    MariaDB [testdb]> insert into students values (0,'小明',18,180.2,2,3,0);
    ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`testdb`.`students`, CONSTRAINT `fkey` FOREIGN KEY (`cls_id`) REFERENCES `classes` (`id`))
    
    #外键约束classes表和students表有联系即classes表下有students表,因为设置外键后并没有允许级联删除,因此无法删除
    MariaDB [testdb]> delete from classes where id=1;
    ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`testdb`.`students`, CONSTRAINT `fkey` FOREIGN KEY (`cls_id`) REFERENCES `classes` (`id`))
    MariaDB [testdb]> delete from classes where id=2;
    ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`testdb`.`students`, CONSTRAINT `fkey` FOREIGN KEY (`cls_id`) REFERENCES `classes` (`id`))
    MariaDB [testdb]> 

    5.4 删除外键

           不知道设置的外键名可以用show create table 查看表名,含有外键信息;

         格式:alter table 表名 drop foreign key 外键名

    MariaDB [testdb]> show create table students;
      CONSTRAINT `fkey` FOREIGN KEY (`cls_id`) REFERENCES `classes` (`id`)
    MariaDB [testdb]> alter table students drop foreign key fkey;
    Query OK, 0 rows affected (0.002 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    MariaDB [testdb]> show create table students;

    5.5 级联删除

    #设置外键允许级联删除
    MariaDB [testdb]> alter table students add constraint fkey1 foreign key(cls_id) references classes(id) on delete cascade;
    MariaDB [testdb]> select * from students order by cls_id;    #按班分类
    +----+-------------+------+-------+---------+------+----------+
    | id  | name       | age  | high  | gender  |cls_id|is_delete |
    +----+-------------+------+-------+---------+------+----------+
    |  1 | 小明         |   18 | 180.0 | 男     |    1 |           |
    |  3 | 彭于晏       |   28 | 185.00 | 男     |    1 |          |
    |  5 | 黄蓉         |  108 | 160.00 | 女     |    1 |          |
    |  8 | 周杰伦儿     |   34 | NULL   | 男     |    1 |          |
    |  7 | 王祖贤       |   52 | 170.00 | 女     |    1 |          |
    | 10 | 和珅         |   55 | 166.00 | 男     |    2 |          |
    |  9 | 程坤         |   44 | 181.00 | 男     |    2 |          |
    |  6 | 凤姐         |   44 | 150.00 | 保密   |    2 |          |
    |  4 | 刘德华       |   58 | 175.00 | 男     |    2 |          |
    |  2 | 小月月       |   19 | 180.00 | 男     |    2 |          |
    | 19 | 小明         |   18 | 180.20 | 女     |    2 |          |
    +----+-------------+------+--------+--------+-------+---------+
    11 rows in set (0.000 sec)
    #现在可以删除classes的数据了
    MariaDB [testdb]> delete from classes where id=1;
    Query OK, 1 row affected (0.001 sec)
    MariaDB [testdb]> select * from students;
    +----+----------+------+--------+--------+-------+----------+
    | id | name     | age  | high   | gender | cls_id| is_delete|
    +----+----------+------+--------+--------+-------+----------+
    |  2 | 小月月    |   19 | 180.00 | 男     |     2 |          |
    |  4 | 刘德华    |   58 | 175.00 | 男     |     2 |          |
    |  6 | 凤姐      |   44 | 150.00 | 保密   |     2 |          |
    |  9 | 程坤      |   44 | 181.00 | 男     |     2 |          |
    | 10 | 和珅      |   55 | 166.00 | 男     |     2 |          |
    | 19 | 小明      |   18 | 180.20 | 女     |     2 |          |
    +----+----------+------+--------+--------+-------+----------+
  • 相关阅读:
    加载spring容器
    id生成工具类
    Spring基础之 反射(Reflection)
    XML解析之dom4j
    我的集合学习笔记--LinkedList
    验证身份证号的正确性
    String系列-----AbstractStringBuilder
    String系列-----String
    Java设计模式-迭代器模式
    Servlet的三个域对象
  • 原文地址:https://www.cnblogs.com/ajunyu/p/10919917.html
Copyright © 2011-2022 走看看