mysql多实例实现
此实验是在基于源码编译安装mariadb之后进行的,如果不知道如何安装,请移步mysql入门之安装篇
数据库安装目录为/app/mysql/
创建多实例数据库的数据库目录和配置目录等相关目录
1 | [root@ansible data]#mkdir /mysql/330{6,7,8}/{etc,data,log,socket,pid} -p |
准备数据库文件
1 | [root@ansible ~]#cd /app/mysql/ |
准备配置文件
将配置文件放到上述规划的etc目录下,并将端口分别改为相应的端口,将socket文件地址指向相应的socket
以使用3307端口的实例配置为例
1 | [root@ansible mysql]#sed -n '/^[^#]/p' 3307/etc/my.cnf |
将/mysql目录的所有者和所属组改为mysql
1 | [root@ansible ~]#chown -R mysql.mysql /mysql |
准备启动脚本
以使用3307端口的实例配置为例
1 | [root@ansible ~]#cat /mysql/3306/mysqld |
将服务脚本加入系统管理服务
1 | [root@ansible ~]#cp /mysql/3306/mysqld /etc/init.d/mysqld3306 |
开启服务并连接
以3307端口实例演示
1 | [root@ansible ~]#service mysqld3307 start |
mysql安全加固
以3307端口实例为例
1 | [root@ansible mysql]#mysql_secure_installation -S /mysql/3307/socket/mysql.sock |
此时,mysql数据库的多实例已经完成。
mysql数据库之增删改查
以下内容只展示命令,不展示执行结果,不然显得太过臃肿,结果可以在测试机自行测试
数据库和表管理
关于字符集,强烈推荐使用utf8mb4字符集
修改数据库实例的字符集方法为:在配置文件mysqld语句块中添加character-set-server=utf8mb4
修改客户端字符集的方法为:在配置文件mysql语句块添加default-character-set=utf8mb4
建议在配置文件中mysqld语句块中写入innodb_file_per_table语句,将每个表的数据单独存放,降低风险。
创建数据库create database
语法:
1 | CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name |
1 | MariaDB [(none)]> create database db_utf8mb4 character set utf8mb4; |
查看mariadb支持的字符集
1 | MariaDB [(none)]> show character set; |
删除数据库
1 | MariaDB [(none)]> drop database testdb; |
创建表 CREATE TABLE
(1) 直接创建
(2) 通过查询现存表创建;新表会被直接插入查询而来的数据
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,…)] [table_options] [partition_options] select_statement
(3) 通过复制现存的表的表结构创建,但不复制数据
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name { LIKE old_tbl_name | (LIKE old_tbl_name) }
注意:
1 | Storage Engine是指表类型,也即在表创建时指明其使用的存储引擎,同一库中不同表可以使用不同的存储引擎 |
字段的数据类型
1、整型
1 | tinyint(m) 1个字节 范围(-128~127) |
2、浮点型(float和double),近似值
1 | float(m,d) 单精度浮点型 8位精度(4字节) m总个数,d小数位 |
3、定点数
1 | 在数据库中存放的是精确值,存为十进制 |
4、字符串(char,varchar,_text)
1 | char(n) 固定长度,最多255个字符 |
char和varchar:
• 1.char(n) 若存入字符数小于n,则以空格补于其后,查询之时再将空格去掉,
所以char类型存储的字符串末尾不能有空格,varchar不限于此
• 2.char(n) 固定长度,char(4)不管是存入几个字符,都将占用4个字节,varchar
是存入的实际字符数+1个字节(n< n>255),所以varchar(4),存入3个字符将
占用4个字节
• 3.char类型的字符串检索速度要比varchar类型的快
varchar和text:
• 1.varchar可指定n,text不能指定,内部存储varchar是存入的实际字符数+1个
字节(n< n>255),text是实际字符数+2个字节。
• 2.text类型不能有默认值
• 3.varchar可直接创建索引,text创建索引要指定前多少个字符。varchar查询速
度快于text
5.二进制数据:BLOB
• BLOB和text存储方式不同,TEXT以文本方式存储,英文存储区分大小写,
而Blob是以二进制方式存储,不分大小写
• BLOB存储的数据只能整体读出
• TEXT可以指定字符集,BLOB不用指定字符集
6.日期时间类型
• date 日期 ‘2008-12-2’
• time 时间 ‘12:25:36’
• datetime 日期时间 ‘2008-12-2 22:06:44’
• timestamp 自动存储记录修改时间
• YEAR(2), YEAR(4):年份
timestamp字段里的时间数据会随其他字段修改的时候自动刷新,这个数
据类型的字段可以存放这条记录最后被修改的时间
修饰符
所有类型:
• NULL 数据列可包含NULL值
• NOT NULL 数据列不允许包含NULL值
• DEFAULT 默认值
• PRIMARY KEY 主键
• UNIQUE KEY 唯一键
• CHARACTER SET name 指定一个字符集
数值型
• AUTO_INCREMENT 自动递增,适用于整数类型
• UNSIGNED 无符号
创建表
直接创建
1 | create table student (id int unsigned auto_increment primary key ,name varchar(10),sex enum('f','m') default 'm',age tinyint unsigned,mobile char(11),address varchar(50)); |
克隆另一张表,并且会将模板表的数据一起克隆
1 | MariaDB [studentdb]> create table employee select * from student; |
克隆另一张表的表结构,但不克隆表中数据
1 | MariaDB [studentdb]> create table custom like student; |
查看表结构
1 | MariaDB [studentdb]> desc student; |
查看表定义
1 | MariaDB [studentdb]> show create table student; |
查看表的信息
1 | MariaDB [studentdb]> show table status like 'student'\G; |
查看某个数据库中的所有表的信息
1 | MariaDB [studentdb]> show table status from database_name\G; |
删除表
1 | MariaDB [studentdb]> drop table student; |
表操作
修改表结构alter
ALTER TABLE ‘tbl_name’
字段:
添加字段:add
ADD col1 data_type [FIRST|AFTER col_name]
删除字段:drop
修改字段:
alter(默认值), change(字段名), modify(字段属性)
索引:
添加索引:add index
删除索引:drop index
表选项
修改:
查看表上的索引:SHOW INDEXES FROM [db_name.]tbl_name;
查看帮助:Help ALTER TABLE
更改字符集
更改库/表字符集
1 | MariaDB [db_utf8mb4]> alter database/table name character set = utf8mb4; |
更改字段的字符集
1 | MariaDB [db_utf8mb4]> alter table table_name change column_name column_name_new character set utf8mb4 |
查看表状态
1 | MariaDB [db_utf8mb4]> show table status like 'student'\G; |
为表增加记录insert
语法
第一种
1 | INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] |
第二种
1 | INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] |
第三种
1 | INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] |
查看表中的记录数
1 | MariaDB [studentdb]> select count(*) from student; |
向表中添加记录
使用第一种方法添加
1 | MariaDB [studentdb]> insert into student (name,age,mobile,adress)values('msq',26,15244059931,'shandong'),('yfq',27,15065002205,'shandong'); |
使用第二种方法添加(不常用)
1 | MariaDB [studentdb]> insert into student set name='mjc',age=1,address='shandong'; |
使用第三种方法添加,批量查询并将查询的结果插入另一个表
1 | MariaDB [studentdb]> insert into custom select * from student; |
删除表中的记录 delete
删除表中的记录时,一定要加限定条件,否则会清空整个表
1 | MariaDB [studentdb]> delete from student where id=4; |
清空表中的数据,但保留表的结构
1 | MariaDB [studentdb]> truncate table student; |
更改表中的记录 update
语法
1 | UPDATE [LOW_PRIORITY] [IGNORE] table_reference |
例如
1 | MariaDB [studentdb]> update student(table_name) set name='zsf' where id=2; |
由于更改表中的记录时,容易出错,建议在客户端连接时加上-U|–safe-updates|–i-am-a-dummy选项,或者直接在配置文件mysql语句块中机上safe-updates
查找数据库的内容
语法
1 | SELECT |
字段显示可以使用别名:
1 | col1 AS alias1, col2 AS alias2, ... |
WHERE子句:指明过滤条件以实现“选择”的功能:
1 | 过滤条件:布尔型表达式 |
模糊匹配:
搜索名字列以m开头的记录,但是尽可能不要使用模糊匹配,会降低服务器性能。
1 | MariaDB [studentdb]> select * from student where name like 'm%'; |
1 | GROUP:根据指定的条件把查询结果进行“分组”以用于做“聚合”运算 |
select单表查询
使用distinct可以对查找到的结果进行去重,之后再显示。
1 | MariaDB [studentdb]> select distinct sex from student; |
导入测试数据库用于练习
1 | [root@ansible ~]#mysql -p -S /mysql/3307/socket/mysql.sock < hellodb_innodb.sql |
用于测试的表格如下
1 | ariaDB [hellodb]> select * from students; |
从中选出性别为女的人
1 | MariaDB [hellodb]> select * from students where gender <> 'm'; #或者where gender = f; |
统计表中记录的总数
1 | MariaDB [hellodb]> select gender,count(gender) from students; |
分组:group by
1 | GROUP:根据指定的条件把查询结果进行“分组”以用于做“聚合”运算 |
统计表中男性和女性人数
1 | MMariaDB [hellodb]> select gender 性别,count(*) 人数 from students group by gender; |
分组:统计每个班的人数
1 | MariaDB [hellodb]> select classid,count(*) from students group by classid; |
多次分组:统计每个班的男生和女生人数
1 | MariaDB [hellodb]> select classid,gender,max(age) from students group by classid,gender; |
分别统计男女平均年龄
1 | MariaDB [hellodb]> select gender 性别,avg(age) 平均年龄 from students group by gender; |
只统计女生的平均年龄
1 | MariaDB [hellodb]> select gender,avg(gender) from students group by gender having gender = 'M'; |
1 | MariaDB [hellodb]> select gender,avg(gender) from students where gender = 'm' group by gender; |
1 | MariaDB [hellodb]> select gender,avg(age) from students where gender='M'; |
统计班级号大于3的班级每个班年龄大于30岁的学生的人数
1 | MariaDB [hellodb]> select classid,count(*) from students where age > 30 group by classid having classid > 3; |
ORDER BY: 根据指定的字段对查询结果进行排序
1 | 升序:ASC |
对学生表中的学生排序,并显示年龄最小的前三个学生
1 | MariaDB [hellodb]> select * from students order by age limit 3; |
对学生表中的学生排序,跳过年龄最小的前三个学生,并显示之后的四个学生
1 | MariaDB [hellodb]> select * from students order by age limit 3,4;+-------+--------------+-----+--------+---------+-----------+ |
对表中班级排序后对年龄倒序
1 | MariaDB [hellodb]> select * from students order by -classid desc,age desc; |
select多表查询
两个表交叉查询
新增一张表
1 | MariaDB [hellodb]> select * from teachers; |
使用union将students表和teachers表纵向合并
union具有自动去重的效果,类似distinct取唯一值。
1 | MariaDB [hellodb]> select stuid,name,age,gender from students union select * from teachers; |
将s、t两张表交叉连接,cross join
1 | MariaDB [hellodb]> select * from students cross join teachers; |
取两个表的交集:内连接
1 | MariaDB [hellodb]> select * from students s,teachers t where s.teacherid=t.tid; |
较新的语法:
1 | MariaDB [hellodb]> select * from students s inner join teachers t on s.teacherid=t.tid; |
取两个表的内连接的特定字段
1 | MariaDB [hellodb]> select classid,s.name,stuid,t.name,tid from students s inner join teachers t on t.tid=s.teacherid; |
左外连接:取出A表的全部记录以及B表中符合条件的记录。
1 | MariaDB [hellodb]> select * from students s left outer join teachers t on s.teacherid=t.tid; |
右外连接:取出B表的全部记录以及A表中符合条件的记录。
1 | MariaDB [hellodb]> select * from students s right outer join teachers t on s.teacherid=t.tid; |
取出只在A表不在B表中的记录
1 | MariaDB [hellodb]> select * from students s left join teachers t on s.teacherid=t.tid where tid is null; |
取出只在B中不在A中的记录
1 | MariaDB [hellodb]> select t.* from students s right join teachers t on s.teacherid=t.tid where s.teacherid is null; |
子查询
选出年龄大于学生平均年龄的老师的记录
1 | MariaDB [hellodb]> select * from teachers where age > (select avg(age) from students); |
完全外连接:左外连接union右外连接
1 | MariaDB [hellodb]> select * from students s left outer join teachers t on s.teacherid=t.tid union select * from students s right outer join teachers t on s.teacherid=t.tid; |
取A、B并集去除交集的部分
1 | MariaDB [hellodb]> select * from (select stuid,s.name student_name,s.age student_age,s.gender student_gender,classid,teacherid,tid,t.name,t.age,t.gender from students s left outer join teachers t on s.teacherid=t.tid union select * from students s right outer join teachers t on s.teacherid=t.tid) f where f.teacherid is null or f.tid is null; |