数据库原理及操作

不羁岁月 提交于 2020-03-29 17:34:06

数据库基础

传统的文件系统管理的缺陷

编写应用程序不方便;
数据冗余不可避免;
应用程序依赖性;
不支持对文件的并发访问;
数据间联系弱
难以按用户视图表示数据;
无阶段性安全控制功能。

数据库管理系统的优点

相互关联的数据的集合;
较少的数据冗余;
程序与数据相互独立;
保证数据的安全、可靠;
最大限度地保证数据的正确性;
数据可以并发使用并能同时保证一致性。

数据库管理系统

数据库是数据的汇集,它以一定的组织形式存在于存储介质上
DBMS是管理数据库的系统软件,它实现数据库系统的各种功能。是数据库系统的核心
DBA: 负责数据库的规划、设计、协调、维护和管理等工作
应用程序指以数据库为基础的应用程序;

关系型数据Key/Value

数据库
关系:关系就是二维表。并满足如下性质:
表中的行、列次序并不在重要
行row:表中的每一行,又称为一条记录(record)
列column:表中的没一列,称为属性,字段
主键(Primary key):用于唯一确定一个记录的字段
域domain:属性的取值范围,如,性别只能是‘男’和‘女’两个值
外键(Foreign key):用于表之间的一对多的关系
唯一键(Uniq key):可以为null,
非关系型数据库:NO SQL(not only SQL)
mencached redis mogoDB
RDBMS
MySQL: MySQL, MariaDB, Percona Server
PostgreSQL: 简称为pgsql,EnterpriseDB
Oracle:
MSSQL:
DB2:
事务tansaction: 多个操作被当作一个整体对待
 ACID:
 A:原子性
 C:一致性
 I:隔离性
 D:持久性
 事务未撤销,形成的数据为:dirt data

数据三要素

数据结构:
 一类是与数据类型、内容、性质有关的对象,比如关系模型中的域、属性和关系等;
另一类是与数据之间联系有关的对象,它从数据组织层表达数据记录与字段的结构
数据的操作:
数据提取:在数据集合中提取感兴趣的内容。SELECT
数据更新:变更数据库中的数据。INSERT、DELETE、UPDATE
数据的约束条件:
是一组完整性规则的集合:

实体(行)完整性 Entity integrity
域(列)完整性 Domain Integrity
参考完整性 Referential Integrity

数据库的正规化分析

RDMBS设计范式基础概念-物理层
 设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同范式,各种范式呈递次规范,越高的范式数据库冗余越小
目前关系数据库有六种范式:-逻辑层
 第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴德斯科范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以次类推。一般说来,数据库只需满足第三范式(3NF)即可
范式
1NF:无重复的列,每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。除去同类型的字段,就是无重复的列
说明:第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库;

​ 2NF:属性完全依赖于主键,第二范式必须先满足第一范式,要求表中的每个行必须可以被唯一地区分。通常为表加上一个列,以存储各个实例的唯一标识PK,非PK的字段需要与整个PK有直接相关性;

​ 3NF:属性不依赖于其它非主属性,满足第三范式必须先满足第二范式。第三范式要求一个数据库表中不包含已在其它表中已包含的非主关键字信息,非PK的字段间不能有从属关系;
为了性能,某些数据库不满足范式,增加了数据库的冗余.

MYSQL概念

历史发展
1979年:TcX公司 Monty Widenius,Unireg
1996年:发布MySQL1.0,Solaris版本,Linux版本
1999年:MySQL AB公司,瑞典
2003年:MySQL 5.0版本,提供视图、存储过程等功能
2008年:Sun 收购
2009年:Oracle收购sun
2009年:Monty成立MariaDB
启动MariaDB服务
初始数据库
]#systemctl start maridb
]#mysql
MariaDB [(none)]>drop database test; #删除数据库test;
MariaDB [(none)]>use mysql;
MariaDB [mysql]> status
MariaDB [mysql] create database testdb;
Query ok,1 row affected (0.00 sec)
MariaDB [mysql]> \! ls /var/lib/mysql
MariaDB [mysql]>SELECT user,password,host FROM user;
]#mysql_secure_installation    #设置mysql密码
]mysql -uroot -p     #输入密码
MariaDB [mysql]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
MariaDB [mysql]> SELECT user,host,password FROM user;
MariaDB [mysql]> SELECT * FROM user\G;
MariaDB [mysql]>quit
交互式命令

可以接受输入重定向。可以source

]#mysql -uroot -proot < test.sql
MariaDB [(none)]> source test.sql
客户端命令

可以不用加“;”结束语句

Note that all text commands must be first on line and end with ';'
?         (\?) Synonym for `help'.
clear     (\c) Clear the current input statement.
connect   (\r) Reconnect to the server. Optional arguments are db and host.
delimiter (\d) Set statement delimiter.
edit      (\e) Edit command with $EDITOR.
ego       (\G) Send command to mysql server, display result vertically.
exit      (\q) Exit mysql. Same as quit.
go        (\g) Send command to mysql server.
help      (\h) Display this help.
nopager   (\n) Disable pager, print to stdout.
notee     (\t) Don't write into outfile.
pager     (\P) Set PAGER [to_pager]. Print the query results via PAGER.
print     (\p) Print current command.
prompt    (\R) Change your mysql prompt.
quit      (\q) Quit mysql.
rehash    (\#) Rebuild completion hash.
source    (\.) Execute an SQL script file. Takes a file name as an argument.
status    (\s) Get status information FROM the server.
system    (\!) Execute a system shell command.
tee       (\T) Set outfile [to_outfile]. Append everything into given outfile.
use       (\u) Use another database. Takes database name as argument.
charset   (\C) Switch to another charset. Might be needed for processing binlog with multi-byte charsets.
warnings  (\W) Show warnings after every statement.
nowarning (\w) Don't show warnings after every statement.
修改MariaDB环境变量
shell的环境变量;
]vim /etc/profile.d/mysql.sh
export  MYSQL_PS1="(\u@\h) [\d]> "
]#. /etc/profile.d/mysql.sh
命令行的选项改变mariadb_PS1;
MariaDB [(none)]> prompt \u@[\D]--->
PROMPT set to '\u@[\D]--->'
root@[MON Jun 4 23:08:30 2018]--->
]mysql --prompt="(\u@\h) [\d]> "
/etc/my.cnf.d/mysql-clients.cnf的文件修改
]vim /etc/my.cnf.d/mysql-clients.cnf
[mysql]
prompt=(\\u@\\h) [\\d]>\\_
Mysql客户端选项
mysql客户端可用选项:
-A, --no-auto-rehash 禁止补全
-u, --user=  用户名,默认为root
-h, --host=  服务器主机,默认为localhost
-p, --passowrd=  用户密码,建议使用-p,默认为空密码
-P, --port=  服务器端口
-S, --socket= 指定连接socket文件路径
-D, --database= 指定默认数据库
-C, --compress  启用压缩
-e "SQL" 执行SQL命令
-V, --version 显示版本
-v --verbose 显示详细信息
--print-defaults 获取程序默认使用的配置
]#mysql -e "show databases;"
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| test               |
+--------------------+

数据库操作

SQL规范
在数据库系统中,SQL语句不区分大小写(建议用大写)
但字符串常量区分大小写
SQL语句可单行货多行书写,以“;”结尾
关键词不能跨多行或简写
用空格和缩进来提高语句的可读性
子句通常位于独立行,便于编辑,提高可读性
注释:
SQL标准:
/注释内容/多行注释
-注释内容 单行注释,注意有空格
MYSQL注释:#
数据库的组件(对象):
数据库、表、索引、视图、用户、存储过程、函数、触发器、事件调度器等

命名规则:
必须以字母开头
可包括数字和三个特殊字符(#_$)
不要使用MYSQL的保留字
同一database(Schema)下的对象不能同名

数据库操作

创建数据库:

CREATE DATABASE|SCHEMA [IF NOT EXTSTS] 'DB_NAME';
CHARACTER SET 'character set name'
COLLATE 'collate name'
删除数据库
DROP DATABASE|SCHEMA [IF EXISTS] 'DB_NAME';
查看支持所有字符集:
SHOW CHLLATION SET;
查看支持所有排序规则:
SHOW COLLATION;
获取命令使用帮助:
mysql>HELP KEYORO;
查看数据库列表:
mysql>SHOW DATABASES;
例如:
MariaDB [(none)]>\! ls /var/lib/mysql
aria_log.00000001  aria_log_control  ibdata1  ib_logfile0  ib_logfile1  mysql  mysql.sock  performance_schema  test
MariaDB [(none)]> CRAETE DATABASE DB1;
MariaDB [(none)]> \! cat /var/lib/mysql/DB1/db.opt
default-character-set=latin1
default-collation=latin1_swedish_ci
MariaDB [(none)]> SHOW CHARACTER SET;   #排序规则
MariaDB [(none)]> DROP DATABASE DB1;    #删除数据库DB1
MariaDB [(none)]> USE DB1
Database [DB1]> SHOW TABLES;
Empty set (0.00 sec)

表的操作

选择正确的数据类型对于获得高性能至关重要,三大原则:

更小的通常更好,尽量使用可正确存储数据的最小数据类型
简单就好,简单数据类型的操作通常需要更少的CPU周期
尽量避免NULL,包含为NULL的列,对MySQL更难优化
表操作
查看所有的引擎:SHOW ENGINES
查看表:SHOW TABLES [FROM db_name]
查看表结构:DESC [db_name.]tb_name
删除表:DROP TABLE [IF EXTSTS] tb_name
查看表创建命令:SHOW CREATE TABLE 'tbl_name'
查看表状态:SHOW TABLE STATUS LIJE 'tbl_name'
查看库中所有表状态:SHOW TABLE STATUS FROM db_name
修改表:不建议修改,修改清备份

MariaDB [DB1]> create table student ( id tinyint unsigned not null primary key,name char(10) not null, phone char(11),sex char(1) );
MariaDB [DB1]> desc student;
MariaDB [DB1]> show table status like 'student'\G;
MariaDB [DB1]> create table emp ( id int unsigned auto_increment primary key, name varchar(30) not null, sex char(1) default 'm', addresss varchar(100) ) engine=innodb default charset=utf8;

Query OK, 0 rows affected (0.01 sec)
MariaDB [DB1]> show create table emp\G;
MariaDB [DB1]> create table user SELECT user,host,password FROM mysql.user;
MariaDB [DB1]> create table user2 SELECT user,host,password FROM mysql.user where 1 = 0;
MariaDB [DB1]> create table user3 like mysql.user;
MariaDB [DB1]> desc user2;

set
多选
enum
二选一
primary key
主键绑定name,city;
MariaDB [DB1]> create table t1 ( name char(30),city char(30), sex char(1),primary key(name,city));

DML语句

DML (Data manipulation Language,数据库操纵语音) 用来查询或者变更
表的记录。DML包含以下几种指令。
SELECT:查询表中的数据
INSERT:向表中插入新数据
UPDATE:更新表中的数据
DELETE:删除表中的数据

insert

MariaDB [DB1]> insert student values(1,'bai','10086','m');
MariaDB [DB1]> insert student(id,name) values(70,wang');
MariaDB [DB1]> insert student(id,name,sex) values(2,'wang','m'),(3,lin','f');
MariaDB [DB1]> insert student set id=4,name='zhao';
MariaDB[DB1]> insert emp(name.adresss) SELECT user,host FROM  user;

update

MariaDB [DB1]> update emp set name='admin',addresss='beijing' where id=1;
MariaDB [DB1]> update emp set name='admin',addresss='beijing' where name='root' LIMIT 2;
delete:慎用
MariaDB [DB1]> truncate table emp;
MariaDB [DB1]> delete FROM emp where id=4;
mysql -U 安全模式
]# vim /etc/my.cnf/mysql-clients.cnf
[mysql]
safe-updates
DQL语句
DDL (Data Definition Languae,数据定义语言) 用来创建或者删除存储
数据用的数据库以及数据库中的表等对象。DDL包含以下几种指令。
CREATE:创建数据库和表等对象
DROP:删除数据库和表等对象
ALTER:修改数据库和表等对象的结构
SELECT

磁盘的数据排放形式来SELECT

syntax:

SELECT
    [ALL | DISTINCT | DISTINCTROW ]
      [HIGH_PRIORITY]
      [STRAIGHT_JOIN]
      [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
      [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
    SELECT_expr [, SELECT_expr ...]
    [FROM table_references
    [WHERE where_condition]
    [GROUP BY {col_name | expr | position}
      [ASC | DESC], ... [WITH ROLLUP]]
    [HAVING where_condition]
    [ORDER BY {col_name | expr | position}
      [ASC | DESC], ...]
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]
    [PROCEDURE procedure_name(argument_list)]
    [INTO OUTFILE 'file_name'
        [CHARACTER SET charset_name]
        export_options
      | INTO DUMPFILE 'file_name'
      | INTO var_name [, var_name]]
    [FOR UPDATE | LOCK IN SHARE MODE]]

#####单表操作

MariaDB [DB1]> SELECT 'hello world';
+-------------+
| hello world |
+-------------+
| hello world |
+-------------+
MariaDB [DB1]> SELECT '1+2',1+2 ;
+-----+-----+
| 1+2 | 1+2 |
+-----+-----+
| 1+2 |   3 |
+-----+-----+
where子句
MariaDB [DB1]> SELECT * FROM user host='localhost';
MariaDB [DB1]> SELECT * FROM student where sex is null;
MariaDB [DB1]> SELECT * FROM student where id >=2 and id <=5;
MariaDB [DB1]> SELECT * FROM student where sex in ('f','m');
MariaDB [DB1]> SELECT * FROM student where sex in ('f','m') or sex is null;
MariaDB [DB1]> SELECT id as 编号,name 姓名 FROM student where sex in ('f','m') or sex is null;  #别名
where子句模糊查询
%:任意长度的任意字符
_:任意单个字符
RLIKE:正则表达式,索引失效,不建议使用
REGEXP:匹配字符串可用正则表达式书写模式,同上
逻辑操作符:
    NOT: !=
    AND:
    OR
    XOR

group

order by
    升序:ASC
    降序:DESC
MariaDB [DB1]> SELECT * FROM student order by score ;
MariaDB [DB1]> SELECT * FROM student order by -score desc;
MariaDB [DB1]> SELECT * FROM student order by score LIMIT 3;

FOR UPDATE LOCK INSHARE MODE

SQL JOINS
LEFT OUTER JOIN
ringt outer join
full join

多表查询
MariaDB [hellodb]> SELECT s.name as s_name,t.name as t_name FROM students as s INNER JOIN teachers as t on s.teacherid=t.tid;
MariaDB [hellodb]> SELECT s.name as s_name,t.name as t_name FROM students as s LEFT OUTER  JOIN teachers as t on s.teacherid=t.tid;
MariaDB [hellodb]> SELECT s.name as s_name,t.name as t_name FROM students as s RIGHT OUTER  JOIN teachers as t on s.teacherid=t.tid;
MariaDB [hellodb]> SELECT st.name,sc.score FROM students as st INNER JOIN scores as sc on st.stuid=sc.stuid and score > (SELECT AVG(score) FROM scores);

子查询
MariaDB [hellodb]> SELECT st.name,sc.score FROM students as st INNER JOIN scores as sc on st.stuid=sc.stuid and score > (SELECT AVG(score) FROM scores);
 view
 类似shell中的别名
MariaDB [hellodb]> create view_oldstu as SELECT * FROM students where age >50;
MariaDB [hellodb]> SELECT * FROM view_oldstu;
MariaDB [hellodb]> drop view_oldstus;

functions

查看函数列表:
SHOW FUNCTIOIN STATUS;
查看函数定义:
SHOW CREATE FUNCTION function_name
删除UDF:
DROP FUNCTION funtion_NAME
调用自定义函数语法:
SELECT function_name(parameter_value,...)
MariaDB [db1]> DELIMITER //
    -> CREATE FUNCTION deleteById(uid SMALLINT UNSIGNED) RETURNS VARCHAR(20)
    -> BEGIN
    -> DELETE FROM students WHERE stuid = uid;
    -> RETURN (SELECT COUNT(uid) FROM students);
    -> END//
MariaDB [db1]> DELIMITER ;
MariaDB [db1]> SELECT deleteById(10)
MariaDB [db1]> SELECT * FROM mysql.proc

存储过程

存储过程优势
 存储过程把经常使用的SQL语句或业务逻辑封装起来,预编译保存在数据库中,当需要时从数据库中直接调用,省去了编译的过程
提高了运行速度
同时降低网络数据传输量

存储过程与自定义函数的区别:
存储过程实现的过程要复杂一些,而函数的针对性较强
存储过程可以有多个返回值,而自定义函数只有一个返回值
存储过程一般独立的来执行,而函数往往是作为其他SQL语句的一部分来使用

存储过程和函数中可以使用流程控制来控制语句的执行

流量控制:

如下:
IF:用来进行条件判断。根据是否满足条件,执行不同语句
CASE:用来进行条件判断,可实现比IF语句更复杂的条件判断
LOOP:重复执行特定的语句,实现一个简单的循环
LEAVE:用于跳出循环控制
ITERATE:跳出本次循环,然后直接进入下一次循环
REPEAT:有条件控制的循环语句。当满足特定条件时,就会跳出循环语句
WHILE:有条件控制的循环语句

MySQL用户和权限管理

用户
元数据数据库:mysql
系统授权表:db,host,user
columns_priv,tables_priv,procs_priv,prixies_priv

用户账号:
USERNAME‘@’HOST’:
@’HOST’:
主机名;
IP地址或Network;
通配符:
%, _: 172.16.%.%
MariaDB [mysql]> create user li@'192.168.36.7' identified by 'centos';
MariaDB [mysql]> RENAME USER old_user_name TO new_user_name
MariaDB [mysql]> DROP USER ''@'localhost';  #删除空用户
MariaDB [mysql]> DROP USER 'USERNAME'@'HOST

密码

正常修改密码
ariaDB [mysql]> SET PASSWORD FOR 'user'@'host' = PASSWORD(‘password');
MariaDB [mysql]> UPDATE mysql.user SET password=PASSWORD('password') WHERE clause;
MariaDB [mysql]> FLUSH PRIVILEGES;
]# mysqladmin -u root –poldpass password 'newpass'
忘记管理员密码的解决办法
]#systemctl stop mariadb
]#vim /etc/my.cnf
[mysqld]
--skip-grant-tables
]#systemctl restart mariadb
]#mysql
MariaDB [mysql]> update user set password=password('centos7') where user='root' ;
]sed -i 's/--skip-grant-tables//' /etc/my.cnf    #删除刚添加的那行
]#systemctl restart mariadb
]#mysql -pcentos7

权限

MariaDB[hellodb]> grant all  on hellodb.* to hong@'192.168.1.%';
MariaDB[hellodb]> grant select,insert on hellodb.* to mage@'%' identified by 'centos';
MariaDB[hellodb]> show grants for mage@'%';
MariaDB[hellodb]> show grants for li@'192.1636.1.%';
MariaDB[hellodb]> REVOKE SELECT ON hellodb.* FROM 'mage'@'%;
MariaDB[hellodb]> FLUSH PRIVILEGES;
注意:MariaDB服务进程启动时会读取mysql库中所有授权表至内存

GRANT或REVOKE等执行权限操作会保存于系统表中,MariaDB的服务进
程通常会自动重读授权表,使之生效

对于不能够或不能及时重读授权表的命令,可手动让MariaDB的服务进程
重读授权表:MariaDB[hellodb]> FLUSH PRIVILEGES;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!