1. 程式人生 > >數據庫原理及操作

數據庫原理及操作

same 基本 字符串 erb 從數據 arguments 必須 函數 pri

數據庫基礎

傳統的文件系統管理的缺陷

編寫應用程序不方便;
數據冗余不可避免;
應用程序依賴性;
不支持對文件的並發訪問;
數據間聯系弱
難以按用戶視圖表示數據;
無階段性安全控制功能。

數據庫管理系統的優點

相互關聯的數據的集合;
較少的數據冗余;
程序與數據相互獨立;
保證數據的安全、可靠;
最大限度地保證數據的正確性;
數據可以並發使用並能同時保證一致性。

數據庫管理系統

數據庫是數據的匯集,它以一定的組織形式存在於存儲介質上
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;

數據庫原理及操作