SQL,英文全称Structured Query Language,中文意思是结构化查询语言。它是一种对关系数据库中的数据进行定义和操作的语言方法,是大多数关系数据库管理系统所支持的工业标准。

SQL分类:
DDL:数据定义语言,CREATE,ALTER,DROP。管理基础数据 <--运维熟练
DCL:数据控制语言,GRANT,REVOKE,COMMIT,ROLLBACK,用户授权,权限回收,数据提交回滚 <--运维要熟悉
DML:数据操作语言,SELECT,INSERT,DELETE,UPDATE,针对数据库里的表里的数据进行操作 <--开发熟练,运维了解

  • 二、数据库基础管理

  • 1、登录MySQL方法

1)单实例MySQL登录的方法
mysql      #无密码登录方式
mysql -u root  #指定用户无密码登录
mysql -uroot -p  #标准dba命令行登录
mysql -uroot -p123456  #非脚本一般不这样使用,密码明文,容易泄露

(2)多实例防止密码泄露登录的方法
设置变量:HISTCONTROL=ignorespace
mysql -uroot -p123456 -S /data/3306/mysql.sock

(3)远程链接登录
mysql -uroot -p -h 192.168.56.11 -P3306
-h 指定ip地址,-P指定端口号
  • 2、MySQL数据库安全策略介绍

1)为root设置比较复杂的密码
(2)删除无用的mysql库内的用户账号,只留root@localhost
(3)删除默认的test数据库
(4)删除用户的时候,授权的权限尽量最小,允许访问的主机范围最小化
(4)针对mysql数据库的用户处理,还有更严格的做法,例如删除root用户,添加新的管理员用户
  • 3、命令讲解

  • (1)创建数据库
    1) 语法:create database 库名;
    (2)查看建表语句:show create database 库名;  
    (3)创建指定字符集的数据库:create database 库名 default character set 字符 collate 校对方式;
    (4)查看字符集:show character set;
    (5)示例:create database test1; 
                        show create database test1;
                        create database test3 default character set utf8 collate utf8_general_ci;    #创建utf8格式
    #如果编译的时候指定了特定的字符集,则以后创建对应字符集的数据库就不需要指定字符集
    
    -DDEFAULT_CHARSET=utf8 \
    -DDEFAULT_COLLATION=utf8_general_ci \
    -DEXTRA_CHARSETS=gbk,gb2312,utf8,ascii \
    #提示:二进制软件包,安装的数据库字符集默认latinl

     

  • (2)切换数据库
    1)语法:use <dbname>2)示例:use test1;

     

  • (3)查看数据库
    1)语法:select database();    #相当于pwd
                    select user();           #查看当前用户
                    select version();       #查看当前版本
                    select now();            #查看当前时间

     

  • (4)删除数据库
    1)语法
    drop database <dbname>2)示例
    drop database test1;

     

  • (5)删除数据库中指定用户
    1)语法:drop user "user"@"主机域"2)要求:可以是单引号,也可以是双引号。但是不能不加。如果主机名中有大写字母的则 drop 删除不了,可以用 delete
    语句来删除 mysql.user 表中的用户。
    delete from mysql.user where user=’root’ and host=’oldboy’;
    flush privileges;
    (3)示例:
    drop user 'root'@'localhost';
    drop user 'system'@"localhost";
    drop user ''@"localhost";
  • (6)创建用户和授权
    1) 查看 GRANT 命令帮助获取创建用户并授权的例子:
    MariaDB [test1]>  help grant;
    CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
    GRANT ALL ON db1.* TO 'jeffrey'@'localhost';
    GRANT SELECT ON db2.invoice TO 'jeffrey'@'localhost';
    GRANT USAGE ON *.* TO 'jeffrey'@'localhost' WITH MAX_QUERIES_PER_HOUR 90;
    
    (2)普通授权方法:先 Create 后 grant
    a、语法
    CREATE USER 'username'@'主机域' IDENTIFIED BY 'mypass';
    GRANT ALL ON dbname.* to 'username'@'localhost'
    
    b、示例
    create user 'user1'@'localhost' identified by '123456';
    grant all on test1.* to 'user1'@'localhost';
    
    (3)运维人员常用创建用户方法:使用 grant 命令在创建用户的同时进行授权
    a、语法 GRANT ALL PRIVILEGES ON dbname.
    * to 'username'@'主机域' identified by 'password'; b、说明 GRANT ALL PRIVILEGES ON dbname.* to 'username'@'主机域' identified by 'password' 授权命令 对应权限 目标:库和表 用户名和客户端主机 用户密码 说明:上述命令是授权localhost主机上通过用户username管理dbname数据库的所有权限,密码为passwd,其中username,dbname,passwd可根据业务的情况修改 对于web连接用户授权尽量采用最小化原则,很多开源软件都是web界面安装,因此在安装期间除了select,insert,update,delete 4个权限外,还需要create,drop等比较危险的权限。 grant select,insert,update,create,drop on blog.* to blog@localhost identified by ‘123’ 常规情况下授权select,insert,update,delete 4个权限即可,有的源软件,例如discuz,bbs还需要create,drop等比较危险的权限。生成数据库表后,要收回create,drop授权 (4)远程主机授权连接数据库 grant 命令的语法中主机域部分为授权访问数据库的客户端主机,可以用域名、 IP 或 IP 段来表示。远程主机 的授权方法有 2 种,具体如下: a、方法一:百分号匹配法 grant all on *.* to test@'192.168.0.%' identified by '123456'; flush privileges; b、方法二:子网掩码匹配法 grant all on *.* to test@'192.168.1.0/24' identified by '123456'; grant all on *.* to test@'192.168.1.0/255.255.255.0' identified by '123456'; flush privileges; #如果是web连接数据库,尽量不要授权all,而是select,insert,update,delete (5)查看权限 MariaDB [test1]> grant all on test1.* to test@'192.168.56.0/24' identified by '123456'; Query OK, 0 rows affected (0.00 sec) MariaDB [test1]> show grants for test@'192.168.56.0/24'; +-------------------------------------------------------------------------------------------------------------------+ | Grants for test@192.168.56.0/24 | +-------------------------------------------------------------------------------------------------------------------+ | GRANT USAGE ON *.* TO 'test'@'192.168.56.0/24' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' | | GRANT ALL PRIVILEGES ON `test1`.* TO 'test'@'192.168.56.0/24' | +-------------------------------------------------------------------------------------------------------------------+ 2 rows in set (0.00 sec) 查看权限可以看出授权是分为 2 步: 第一步是授权可登陆 GRANT USAGE ON *.*。 USAGE 表示只有登陆权限。 第二步是授权可访问 ON `test1`.* TO 'test'@'192.168.56.0/24'6)权限回收 MariaDB [test1]> revoke insert on test1.* from test@'192.168.56.0/24'; Query OK, 0 rows affected (0.01 sec) MariaDB [test1]> show grants for test@'192.168.56.0/24'; +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Grants for test@192.168.56.0/24 | +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | GRANT USAGE ON *.* TO 'test'@'192.168.56.0/24' IDENTIFIED BY PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9' | | GRANT SELECT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER ON `test1`.* TO 'test'@'192.168.56.0/24' | +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 2 rows in set (0.00 sec) #MySQL 权限列表如下 SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, ALTER, CREATE TEMPORARY, TABLES, LOCK TABLES, EXECUTE, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EVENT, TRIGGER MySQL包含关系 :数据库服务器>数据库(多个实例)>多个库>多个表>多个字段行列(数据)

     

  • (7)创建表
    1)语法:create table <表名><字段名1><类型n>);
    提示:其中create table是关键字,不能更改,但是大小写可以变化
    
    (2)下面是人工写法设计的建表语句例子,表名student
    create table student(
        id int(4) not null,
        name char(20) not null,
        age tinyint(2)  NOT NULL default '0',
        dept varchar(16)  default NULL
        );
    
    (3)查看创建表的语句
    mysql> show create table student;
    create table student(       #create table表示创建表的固定关键字,student为表名
    id int(4) not null,        #学号列,数字类型,长度为4,不能为空值
    name char(20) not null,    #名字列,定长字符类型,长度20,不能为空
    age tinyint(2)  NOT NULL default '0', #年龄列,很小的数字类型,长度为2,不能为空,默认为0值
    dept varchar(16)  default NULL    #性别列,变长字符类型,长度16,默认为空。
    ENGINE=lnnoDB DEFAULT CHARSET=latinl  #引擎和字符集,引擎默认为InnoDB,字符集,继承库的latinl
    );
    
    #需要注意的事:MySQL5.1和MySQL5.5 
    环境的默认建表语句中的引擎的不同,如果希望控制引擎,就要在建表语句里显示的指定引擎建表;MySQL5.1以及默认引擎为MyISAM,MySQL5.5,以后默认引擎为InnoDB。

     

  • (8)生产场景案例
    某sns产品生产正式建表语句
    use sns; set names gbk; CREATE TABLE `subject_comment_manager` ( `subject_comment_manager_id` bigint(
    12) NOT NULL auto_increment COMMENT '主键', `subject_type` tinyint(2) NOT NULL COMMENT '素材类型', `subject_primary_key` varchar(255) NOT NULL COMMENT '素材的主键', `subject_title` varchar(255) NOT NULL COMMENT '素材的名称', `edit_user_nick` varchar(64) default NULL COMMENT '修改人', `edit_user_time` timestamp NULL default NULL COMMENT '修改时间', `edit_comment` varchar(255) default NULL COMMENT '修改的理由', `state` tinyint(1) NOT NULL default '1' COMMENT '0代表关闭,1代表正常', PRIMARY KEY (`subject_comment_manager_id`), KEY `IDX_PRIMARYKEY` (`subject_primary_key`(32)), #<==括号内的32表示对前32个字符做前缀索引。 KEY `IDX_SUBJECT_TITLE` (`subject_title`(32)) KEY `index_nick_type` (`edit_user_nick`(32),`subject_type`)#<==联合索引,此行为新加的,用于给大家讲解的。实际表语句内没有此行。 ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
  • 4、索引

  • (1)为表的字段创建索引

索引就象书的目录一样,如果在字段上建立了索引,那么以索引为查询条件时可以加快查询数据的速度.
创建主键索引
查询数据库,按主键查询是最快的,每个表只有一个主键列,但是可以用多个普通索引列。主键列要求列的所有内容必须唯一,而普通索引不要求内容必须唯一
主键就类似我们在学校学习时的学号一样,班级内是唯一的,整个表的每一条记录的主键值在表内都是唯一的,用来唯一标识一条记录。

(1)建立主键索引的方法:
drop table student;
create table student(
id int(4) not null AUTO_INCREMENT,
name char(20) not null,
age tinyint(2)  NOT NULL default '0',
dept varchar(16)  default NULL,
primary key(id),
KEY index_name(name)
);

#提示: 
# primary key(id)<==主键 
# KEY index_name(name)<==name字段普通索引

(2)mysql> desc student; 查看刚刚创建的表结构。
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(4)      | NO   | PRI | NULL    | auto_increment |
| name  | char(20)    | NO   | MUL | NULL    |                |
| age   | tinyint(2)  | NO   || 0       |                |
| dept  | varchar(16) | YES  |     | NULL|                |
+-------+-------------+------+-----+---------+----------------+

#PRL为主键的标示,MUL为普通索引的表示 ,auto_increnment 代表数据自增

(3)利用alter命令修改id列为自增主键值
alter table student change id id int primary key auto_increment; 

创建的表的时候,可以指定
mysql> create table student(
id int(4) not null AUTO_INCREMENT,
name char(20) not null,
age tinyint(2) NOT NULL default '0',
dept varchar(16)  default NULL,
primary key(id),
KEY index_name(name)      
);

提示:
KEY index_name(name)               <==name字段普通索引
优化:在唯一值多的列上建索引查询效率高
还可以自定义自增的长度
EBGUBE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

(4)查看索引【前提都需要进入库】
show index from student; 
查看索引\G 可以查看的更详细:show index from student\G      
  • (2)查看表结构

1)语法:desc 表名
(2)示例:desc student; 
  • (3)建表后利用alter增加普通索引,删除建表时创建的index_name索引

1)语法:alter table 表名 add|drop index 索引名称
alter table student add index index_name;
alter table student drop index index_name;
2)示例: create index index_name on student(name); #创建索引 show index from student; #查看索引 create index index_age on student(name(8)); #创建指定n个字符索引 show index from student\G #查看索引
  • (4)为表的多个字段创建联合索引

如果查询数据的条件是多列时,我们可以为多个查询的列创建联合索引,甚至,可以为多个列的前n个字符创建联合索引,演示如下:
创建联合索引,和单个索引不冲突

 create index ind_name_dept on student(name,dept);    #在student表创建联合索引
 联合索引作用,查询更快
 show index from student\G
 创建联合索引,并指定值大小:
 create index ind_name_dept on student(name(8),dept(10));
#name 前8个字符,dept 前10个字符
#提示:尽量在唯一值多的大表上建立索引。

什么时候创建联合索引?

只有程序用这两个条件查询,采用联合索引,这个主要是看开发。 
提示:按条件列查询数据时,联合索引是由前缀生效特性的

  • (5) 创建唯一索引(非主键)

create unique index uni_ind_name on student(name);
  • (6)索引小结:

创建主键索引:
alter table student chage id id int primary key auto_increment;
删除主键索引(主键列不能自增): alter table student drop primary key;
添加普通索引: alter table student add index index_dept(dept);
根据的前n个字符创建索引: create index index_dept on student(dept(
8));
根据多个列创建联合索引: create index index_name_dept on student(name,dept);
创建唯一索引: create unique index uni_ind_name on student(name);
删除普通索引与唯一索引: alter table student drop index index_dept; drop index index_dept on student;
  • (7)索引列的创建及生效条件

Q1:既然索引可以加快查询速度,那么就给所有的列加索引吧?
A1:因为索引不但占用系统空间,而且更新数据时还需要维护索引数据的,因此索引是一把双刃剑,并不是越多越好,例如:数十到几百行的小表上无需建立索引,插入更新频繁,读取比较少的需要少建立索引.

Q2:需要在哪些列上创建索引才能加快查询速度呢?
select user,host from mysql.user where
password=…..,索引一定要创建在where后的条件列上,而不是select后的选择数据的列上。另外,我们要尽量选择在唯一值多的大表上的列建立索引,例如,男女生性别列唯一值少,不适合建立索引。
  • (8)查看唯一值数量

select count(distinct user) from mysql.user;
唯一值就是相同的数量,例如查询user那么相同的user就是唯一值
  • (9)创建索引的基本知识小结:

■ 索引类似书籍的目录,会加快查询数据的速度 
■ 要在表的列(字段)上创建索引 
■ 索引会加快查询速度,但是也会影响更新的速度,因为更新要在维护索引数据 
■ 索引列并不是越多越好,要在频繁查询的表语句where后的条件列上创建索引 
■ 小表或重复值很多的列上可以不建索引,要在大表以及重复值少的条件上创建索引 
■ 多个列联合索引有前缀生效特性 
■ 当字段内容前N个字符已经接近唯一时,可以对字段的前N个字符创建索引 
■ 索引从工作方式区别,有主键,唯一,普通索引 
■ 索引类型有BTREE(默认)和hash(适合做缓存(内存数据库))等。


  • (10)主键索引和唯一索引的区别

(1)对于主键/unique constraint oracle/sql server/mysql等都会自动建立唯一索引; 
(2)主键不一定只包含一个字段,所以如果你在主键的其中一个字段建唯一索引还是必要的; 
(3)主健可作外健,唯一索引不可; 
(4)主健不可为空,唯一索引可; 
(5)主健也可是多个字段的组合; 
(6)主键与唯一索引不同的是: 
a.有not null属性; 
b.每个表只能有一个。
  • 5、往表中插入数据

1)命令语法:insert into <表名>[(<字段名1>[..<字段名n>])]values(值1)[,(值n)]
(2)建立测试表:
CREATE TABLE `test1` (
  `id` int(4) NOT NULL,
  `name` char(16) NOT NULL,
  `age` int(2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
(3)插入值
insert into test1(id,name,age) values(1,'gaoyuliang',60);
insert into test1 values(2,"xiaoqiang",12);
(4)查询
select * from test1;
+----+------------+------+
| id | name       | age  |
+----+------------+------+
|  1 | gaoyuliang |   60 |
|  2 | xiaoqiang  |   12 |
+----+------------+------+5)批量插入
insert into test1 values(3,'xiaohong',20),(4,'xiaogang',23);
MariaDB [oldboy]> select * from test1;
+----+------------+------+
| id | name       | age  |
+----+------------+------+
|  1 | gaoyuliang |   60 |
|  2 | xiaoqiang  |   12 |
|  3 | xiaohong   |   20 |
|  4 | xiaogang   |   23 |
+----+------------+------+6)清空表中所有值
MariaDB [oldboy]> truncate table test1;
Query OK, 0 rows affected (0.00 sec)

MariaDB [oldboy]> select * from test1;
Empty set (0.00 sec)

(7)一条命令创建
MariaDB [oldboy]> insert into test1 values (1,'oldboy',40),(2,'oldgirl',60),(3,'inca',20),(4,'zuma',30),(5,'kaka',33);
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

MariaDB [oldboy]> select * from test1;
+----+---------+------+
| id | name    | age  |
+----+---------+------+
|  1 | oldboy  |   40 |
|  2 | oldgirl |   60 |
|  3 | inca    |   20 |
|  4 | zuma    |   30 |
|  5 | kaka    |   33 |
+----+---------+------+
5 rows in set (0.00 sec)
View Code

相关文章:

  • 2022-12-23
  • 2021-04-01
  • 2021-07-06
  • 2021-08-28
  • 2021-09-14
  • 2022-12-23
  • 2021-07-08
猜你喜欢
  • 2021-05-27
  • 2021-10-03
  • 2021-12-03
  • 2021-06-09
  • 2022-01-01
相关资源
相似解决方案