Mysql超基础知识速学笔记基礎語法速查

一基本概念

  1. 关系型数据库和非关系型数据库

    sql 和NoSql(not only sql)

  2. MySql

    是一个软件,是关系型数据库管理系统RDBMS Relational Database Management System

二安装

1、MySql 5.0版本的安装

  1. 下载压缩版本的安装包

  2. 配置系统变量,并在根目录下配置ini文件

    [mysqld]
    basedir=D:\Program Files\mysql-5.7\
    datadir=D:\Program Files\mysql-5.7\data\
    port=3306
    skip-grant-tables
    
  3. 管理员模式运行cmd,并到bin目录下

  4. 安装mysql

    mysqld -install

  5. 初始化数据文件

    mysqld --initialize-insecure --user=mysql

  6. 启动mysql,并进入管理界面

    net start mysql

    mysql –u root –p

  7. 修改root密码

    update mysql.user set authentication_string=password('123456') where user='root'and Host = 'localhost';
    
  8. 刷新权限

    flush privileges;
    
  9. 修改 my.ini文件删除最后一句skip-grant-tables

  10. 重启

    exit
    net stop mysql
    net start mysql
    

2、安装SQLyog或Navicat

字符集:utf-8

字符核对集:utf-8_general_ci

三数据库实操

1、基本sql语句在cmd的使用

net start mysql --启动数据库服务

net stop mysql -- 关闭数据库服务

exit --退出服务

mysql -u(root) -p(password) --进入管理界面
-------------------------------------------------
--所有的sql语句后面都要加分号“;”
show databases; --显示所有数据库

mysql> use onlinemall --使用某一个数据库
Database changed

mysql> show tables; --把某一个数据库中所有表显示

describe 某个表名 --描述某一个表

create database xxx --创建一个数据库

2、操作数据库

  1. 创建数据库

    CREATE DATABASE [IF NOT EXISTS] school  CHARACTER  SET utf8 COLLATE utf8_general_ci
    --创建一个的数据库
    
  2. 删除数据库

    DROP DATABASE [IF EXISTS] school -- 删除一个数据库
    
  3. 使用数据库

    USE school 
    
  4. 查看数据库

    SHOW DATABASES
    

3、(列)数据类型

  1. 数值类型

    • tinyint 相当于byte 1个字节
    • smallint 相当于short 2个字节
    • mediumint 3个字节
    • int 相当于普通int 4个字节
    • bigint 相当于long 8个字节
    • float 4个字节
    • double 8个字节
    • decimal 字符串形式的浮点数, 金融计算
  2. 字符串类型

    • char 字符串固定大小的 0~255
    • varchar 可变字符串 0~65535 个字节
    • tinytext 微型文本 2^8 - 1
    • text 文本串 2^16 - 1
  3. 日期类型

    • date YYYY-MM-DD
    • time HH:mm:ss
    • datetime YYYY-MM-DD HH:mm:ss 最常用
    • timestamp 时间戳,从1970.1.1的毫秒数
    • year 年份
  4. null

    • 没有值,未知
    • 不要使用NULL进行运算,否则结果为空

4、字段属性

主键、非空、长度(int的长度和存储大小没关系)、Unsigned、自增、Zerofill

注意,字符串的Null和""是不一样的。

5、创建数据库

注意要在USE 数据库后选中才能直接执行。

公式:

CREATE TABLE [判断条件]`表名`(
    `字段名` 字段类型 + 字段属性,
    `字段名` 字段类型 + 字段属性,
    `字段名` 字段类型 + 字段属性,
    设置主键
)设置引擎,设置默认字符集

例子:

CREATE TABLE IF NOT EXISTS`teacher`(
    `id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '老师编号',
    `name` VARCHAR(10) NOT NULL DEFAULT '匿名' COMMENT '老师姓名', 
    --------设置默认值的时候和注释的时候,要用英文的单引号 
    `age` INT(3) NOT NULL DEFAULT '0' COMMENT '老师年龄',
    PRIMARY KEY (`id`)  -----设置主键要用括号括起来 
)ENGINE=INNODB DEFAULT CHARSET=utf8  ---注意等号

相对/相反的常用命令:

SHOW CREATE DATABASE `onlinemall`  --得到创建该数据库的语句
SHOW CREATE TABLE `users`          --得到创建该表的语句
desc(describe) `表名`               --得到某一个表的详细信息

6、修改删除表中字段

------------------------修改表-----------------------------
主关键字:
- alter
- rename as
- add
- drop
- modify\change
--修改表名 
ALTER TABLE teacher RENAME AS teachers

--增加字段
ALTER TABLE `teachers` ADD `birthday` DATETIME NOT NULL

--删除字段
ALTER TABLE `teachers` DROP `birthday`

----改变字段
--modify不能重命名,但可以改变类型和约束
--change可以重命名,并可以改变类型和约束
ALTER TABLE `teachers` MODIFY age VARCHAR(3) NOT NULL

ALTER TABLE `teachers` CHANGE age age1 VARCHAR(3)

--删除表
DROP TABLE `teachers`

四、数据库管理

1、物理外键

**创建方式一:**在创建表的同时增加外键

CREATE TABLE `grade`(
    `gradeID` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年级编号',
    `name` VARCHAR(10) NOT NULL COMMENT '年级名称',
    PRIMARY KEY (`gradeID`)
)ENGINE=INNODB DEFAULT CHARSET=utf8


CREATE TABLE `teacher`(
    `id` INT(10) NOT NULL DEFAULT '0' COMMENT '老师ID',
    `name` VARCHAR(10) NOT NULL DEFAULT '匿名' COMMENT '老师姓名',
    `age` INT(3) NOT NULL DEFAULT '0' COMMENT '老师年龄',
    `gradeID` INT(10) NOT NULL COMMENT '老师所属的年级',
    PRIMARY KEY (`id`),
    KEY `FK_gradeID` (`gradeID`),--声明
    CONSTRAINT `FK_gradeID` FOREIGN KEY (`gradeID`) REFERENCES `grade` (`gradeID`)
    --添加约束,引用
)ENGINE=INNODB DEFAULT CHARSET=utf8

**创建方式二:**在已有的表的基础上增加外键

CREATE TABLE `grade`(
    `gradeID` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年级编号',
    `name` VARCHAR(10) NOT NULL COMMENT '年级名称',
    PRIMARY KEY (`gradeID`)
)ENGINE=INNODB DEFAULT CHARSET=utf8


CREATE TABLE `teacher`(
    `id` INT(10) NOT NULL DEFAULT '0' COMMENT '老师ID',
    `name` VARCHAR(10) NOT NULL DEFAULT '匿名' COMMENT '老师姓名',
    `age` INT(3) NOT NULL DEFAULT '0' COMMENT '老师年龄',
    `gradeID` INT(10) NOT NULL COMMENT '老师所属的年级',
    PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

-----完成创建表后,用alter关键字和add关键字增加外键
ALTER TABLE `teacher`
ADD CONSTRAINT `FK_gradeID` FOREIGN KEY (`gradeID`) REFERENCES `grade` (`gradeID`)

2、DML语言

database manipulation language–数据库操作语言

insert语句
--公式:insert into 表名(字段名) values (‘值’,‘值……),(’值‘,’值‘,……)
---公式中字段名可以省略,但省略后要把所有的值全部填充上

INSERT INTO `student` (`name`,`age`,`test`)
VALUES ('傻22子',15,'slf'),
('憨11憨',18,'lsf')
update语句
--公式:update 表名 set 字段名=值,字段名=值 where 子句
--注意,如果不回where是非常危险的,会改变所有记录的值

UPDATE `student` SET `name`='aaa' WHERE id='11' AND age='12'
delete和truncate语句

delete:

--公式:delete from 表名 where 条件
--
DELETE FROM `student` WHERE id='34'

truncate:

--公式:truncate [table] 表名
TRUNCATE TABLE `student` 

区别(当delete不加where条件子句的时候):

  • truncate 会重新设置自增列 计数器会归零
  • truncate 不会影响事务

delete删除问题:

  • innoDB 自增列会重1开始 (存在内存中,断电即失)
  • myisam 继续从上一个自增量开始 (存在文件中的,不会丢失)
select语句

关键字顺序

SELECT[ALL|DISTINCT|DISTINCTROW|TOP]
{
   
   *|talbe.*|[table.]field1[AS alias1][,[table.]field2[AS alias2][,]]}
FROM tableexpression[,][IN externaldatabase]
[WHERE]
[GROUP BY]
[HAVING]
[ORDER BY]
[LIMIT offset,row_count]

基本语法:

--选择所有字段:
SELECT * FROM `student`

--选择特有字段
SELECT `id`,`name` FROM `student`

--起别名
SELECT `id` AS 编号,`name` AS 姓名 FROM `student` AS 学生表

--用concat函数连接结果
SELECT CONCAT('编号:',`name`) AS 编号列 FROM `student` AS 学生表

去重及表达式:

--去重关键字:distinct
SELECT DISTINCT `name` FROM `teacher`

-----------------------
--表达式
--数据库中的表达式种类:文本值、列、NULL、函数、计算表达式、系统变量

SELECT 8+9 AS 计算结果  --计算表达式

SELECT `age` + 1 AS1后的值 FROM `teacher` --列加上计算表达式

SELECT VERSION() --函数

SELECT @@auto_increment_increment --变量

3、where及模糊查询

逻辑运算符

运算符 语法 描述
<> 表示不等于
and && where a and b a && b
or || where a or b a || b 或,会改变 A并B 的集合
Not ! where not number=3 !(number=3)

模糊搜索

运算符 语法 描述 注意点
is null where 字段名 is null 如果记录为空则满足条件 空字符不是NULL
is not null
between 是一个闭区间
like where 字段名 like ‘具体匹配’ 多字符匹配 “_”代表一个字符,而“%”代表多个字符。like后面的条件必需用英文单引号包起来!
in where 字段名 in (‘值’,‘值’) 查询记录在in括号里面的值 是精确匹配!

4、联表查询join on语句

知识点:

  • 七种join理论
  • where条件与on条件的区别
  • 多表联合查询

注意点:

  • ambigious错误
--下面是查询商品已经有购买记录的需求
SELECT g.goodID, NAME
FROM `goods` AS g
LEFT JOIN `orders` AS o
ON g.goodID = o.goodID
WHERE o.goodID IS NOT NULL

5、自连接

  • 可以理解为树结构
CREATE TABLE `school`.`category`(
 `categoryid` INT(3) NOT NULL COMMENT 'id', 
 `pid` INT(3) NOT NULL COMMENT '父id 没有父则为1', 
 `categoryname` VARCHAR(10) NOT NULL COMMENT '种类名字', 
 PRIMARY KEY (`categoryid`) 
 ) ENGINE=INNODB CHARSET=utf8 COLLATE=utf8_general_ci; 

INSERT INTO `school`.`category` (`categoryid`, `pid`, `categoryname`) VALUES ('2', '1', '信息技术');
INSERT INTO `school`.`CATEGOrY` (`categoryid`, `pid`, `categoryname`) VALUES ('3', '1', '软件开发');
INSERT INTO `school`.`category` (`categoryid`, `PId`, `categoryname`) VALUES ('5', '1', '美术设计');
INSERT INTO `School`.`category` (`categoryid`, `pid`, `categorynamE`) VALUES ('4', '3', '数据库'); 
INSERT INTO `school`.`category` (`CATEgoryid`, `pid`, `categoryname`) VALUES ('8', '2', '办公信息');
INSERT INTO `school`.`category` (`categoryid`, `pid`, `CAtegoryname`) VALUES ('6', '3', 'web开发'); 
INSERT INTO `SCHool`.`category` (`categoryid`, `pid`, `categoryname`) VALUES ('7', '5', 'ps技术');


---爸爸找儿子,儿子找爸爸
SELECT a.categoryname AS 父亲栏,b.categoryname AS 儿子栏
FROM `category` AS a,`category` AS b
WHERE a.`categoryid` = b.pid

6、排序与分页

排序

-- ASC是升序 ==》ascend 上升
-- DESC是降序 ==》 descend 下降
-- 不加关键字相当于升序,即相当于加了ASC
SELECT `name` AS 商品名,`price` AS 价格
FROM `goods` 
ORDER BY `price` ASC

分页:

-- limit 第一个参数是分页起始值,也就是从哪个记录开始
--       第二个参数是分页面的大小
-- 公式: LIMIT (当前页数 - 1) * 页面大小,页面大小
-- 总页数 = (总数据量大小 / 页面大小) 向上取整。(不是加1,因为整除的时候加1不行)
SELECT `name` AS 商品名,`price` AS 价格
FROM `goods` 
ORDER BY `price` ASC
LIMIT 0,10

7、子查询与嵌套查询

-- 嵌套查询中,是从里面计算到外面的
SELECT `name` AS 已经有购买的商品名, `price` AS 价格 
FROM `goods` 
WHERE `goodID` IN (-- 子查询中,如果有多个记录,要用in,不能用 = 
SELECT `goodID` FROM `orders` 
)

8、常用函数与聚合函数

https://dev.mysql.com/doc/refman/5.7/en/sql-function-reference.html

常用函数:

--数学函数
SELECT ABS(-10)
SELECT CEILING(9.4)
SELECT FLOOR(9.4)
SELECT RAND()
SELECT SIGN(-10)

--字符处理函数
SELECT CHAR_LENGTH('钟包子')
SELECT CONCAT('你好','世界')
SELECT CHAR_LENGTH('钟包子')
SELECT CONCAT('你好','世界')
SELECT UPPER('zhongxiaohao')
SELECT LOWER('QQ.com')


--日间和日期函数
SELECT CURRENT_TIME()   --22:46:01
SELECT CURRENT_DATE()   --2020-11-10
SELECT CURDATE()  --2020-11-10
SELECT NOW() --2020-11-10 22:45:36
SELECT LOCALTIME()    --本地时间2020-11-10 22:46:26
SELECT SYSDATE()   -- 系统时间2020-11-10 22:46:52
--- 下面都要用一个date对象为参数
SELECT YEAR(CURRENT_TIME()) 
SELECT MONTH(CURRENT_DATE())
SELECT DAY(CURDATE())
SELECT HOUR(NOW())
SELECT MINUTE(LOCALTIME())
SELECT SECOND(SYSDATE())


--系统
SELECT SYSTEM_USER()  --root@localhost
SELECT USER()  --root@localhost
SELECT VERSION()  --5.7.15

聚合函数:

定义:聚合函数是对列中的一系列数据进行处理,返回单个统计值。针对表中一列或者多列数据的分析就称为聚合分析

-- count,sum,max,mim,avg
SELECT SUM(`price`) AS 订单产生的总价值
FROM `orders` o
INNER JOIN `goods` g
ON o.goodID = g.goodID

-- 重点:count(字段)  会忽略所有的NULL值
--count(*)  不会忽略所有的NULL值
--count(1)   不会忽略所有的NULL值
--- 的区别与联系

9、分组过滤

**出现报错:**mysql sql_mode=only_full_group_by

对于group by聚合操作,如果在select中的列没有在group by中出现,那么这个SQL是不合法的,因为列不在group by从句中,所以设置了sql_mode=only_full_group_by的数据库,在使用group by时就会报错,

既然知道了问题,那么修改这个配置就可以了,找到MySQL的配置文件,my.ini文件,手动添加进去:

sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
需要注意的一点是一定要添加在[mysqld]配置内,这样添加完后重启mysql才会生效,退出数据库:exit,重启命令:

-- 下面的功能是查找用户购买的最高价格的商品,并且最高价格要大于20元
-- 需要注意的是,如果条件中含有聚合函数,则只能用having,而不能用where
-- having是对结果进行二次过滤,如果查询的栏目中没有某个栏目,那个having不能引用该某个栏目
SELECT u.`userName`,`nickName`,`name`,MAX(`price`)
FROM `orders` o
INNER JOIN goods g
ON o.goodID = g.`goodID` --联合查询到商品的名字
INNER JOIN users u
ON o.userName = u.userName  --联合来查询到用户的名字
GROUP BY u.`userName` --用用户名来分组
HAVING MAX(`price`) >= 20  --要满足最高价格大于20
-- HAVING u.`userName`='guest'  --如果写成o.userName,则会提示找不到该栏目

五、扩展知识

1、数据库级别MD5加密算法

  • MD5 信息摘要算法 message-digest algorithm
  • 不可逆,只能正向加密
  • 应用:对用户注册的密码进行MD5加密,然后放入数据库中。用户登录的时候,将其输入的密码进行MD5加密,和数据库中的暗文进行匹配。可以进行二次加密。
-- 语法:直接调用Mysql内置的函数即可
SELECT MD5('你好吧')

2、事务

1、基本概念

参考博文:https://blog.csdn.net/dengjili/article/details/82468576

事务管理的四个基本特点(ACID):

  • 原子性(Atomicity)

    事务的操作要么全部发生,要么全部不发生

  • 一致性(Consistency)

    事务提交前后,数据完整性一致(如转钱,钱总数不变)

  • 隔离性(Isolation)

    不同事务之间互不干扰

  • 持久性(Durability)

    事务提交后,对数据的改变是永久的

由于隔离性带来的三个读取问题:

  • 脏读(read out of invaild data)

    一个事务读取了别一个未提交的事务的数据

  • 不可重复读

    一个事务多次读取同一个数据,多次读取的结果不同

  • 虚读/幻读(phantom read)

    一个事务内读取了别的事务插入的数据,导致前后读取不一致。(一般是行影响,多了一行)

2、语法
SET autocommit = 0;  ------设置事务自动提交关闭

START TRANSACTION --事务开始

UPDATE `student` SET `name`='黄' WHERE id='1' --一旦执行,数据库的数据会立即变,但没有持久化
UPDATE `student` SET `age`='19' WHERE id='1'

COMMIT   --提交事务
ROLLBACK  --事务回滚

SET autocommit = 1  --设置事务自动提交开启

3、索引

相关文章:http://blog.codinglabs.org/articles/theory-of-mysql-index.html

索引分类

  • 主键索引

    • 唯一的标识,不可重复,只能有一个列作为索引
  • 唯一索引

    • 记录不可重复(除了NULL以外),但一个表中可以有多个 唯一索引
  • 常规索引

    • 没有任何限制
  • 全文索引

    • 在特定的数据库引擎都有,MyISAM有
    • 快速定位数据

语法

-- 总共有三种方式可以创建索引

-- ---------------方法一:在创建表的时候定义索引----------------------------
CREATE TABLE `test`(
    `id` INT(10) NOT NULL,
    `name` VARCHAR(20) NOT NULL,
    `age` INT(100) NOT NULL,
    `address` VARCHAR(30) NOT NULL, 
    PRIMARY KEY(`id`),  --主键索引
    UNIQUE `name`(`name`),  --唯一索引
    KEY `age`(`age`),    --普通索引,也可以用INDEX,等效于KEY
    FULLTEXT `address`(`address`)--全文索引用int类型会报错(不知道为什么)
)ENGINE=INNODB DEFAULT CHARSET=utf8

-- --------------------方法二:利用create语句------------------------
CREATE UNIQUE INDEX indexName ON mytable(username(length)) 

CREATE UNIQUE INDEX `name` ON `test`(`name`(2))
CREATE INDEX `age` ON `test`(`age`)
CREATE FULLTEXT INDEX `name` ON `test`(`name`)



-- ---------方法三:利用alter语句-------------------
ALTER TABLE tbl_name ADD PRIMARY KEY (column_list)-- 该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL。

ALTER TABLE tbl_name ADD UNIQUE index_name (column_list)-- 这条语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)。

ALTER TABLE tbl_name ADD INDEX index_name (column_list)--添加普通索引,索引值可出现多次。

ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list)--该语句指定了索引为 FULLTEXT ,用于全文索引。


ALTER TABLE `test` ADD INDEX `name`(`name`)
ALTER TABLE `test` ADD PRIMARY KEY `id`(`id`)

其它:

  • explain 用于分析执行的sql语句
  • show index from table_name 显示表中所有的索引
  • DROP INDEX [indexName] ON mytable; 删除索引

索引原则:

  • 索引不是越多越好
  • 不要对经常变动的数据加索引
  • 小数据量的表不需要加索引
  • 索引一般加在常用来查询的字段上

4、用户管理

-- 创建用户
CREATE USER testUser2 IDENTIFIED BY '232323'

-- 修改密码(修改当前密码)
SET PASSWORD = PASSWORD('123456')

--- 修改密码(给特定用户)
SET PASSWORD FOR testUser2 = PASSWORD('232323')

--- 给用户重命名
RENAME USER testUser2 TO testUser3

---给用户授权 库.表
GRANT ALL PRIVILEGES ON *.* TO testUser3

---查询权限
SHOW GRANTS FOR testUser3

---撤销权限
REVOKE ALL PRIVILEGES ON *.* FROM testUser3

---删除用户
DROP USER testUser3

5、备份

方式一: 直接拷贝data目录(物理文件)

方式二: 可视化操作

方式三: 命令行

-- 导入数据库
-- mysqldump -h服务器地址(可远程) -u -p  数据库名 【表1 表2】  > 物理地址
mysqldump -hlocalhost -uroot -p123456 school grade student > d:/school.sql

-- 导入数据库
--------------方式1-----------------
--1.登入数据库管理界面
--2.用source + 物理文件地址
--(注意:如果导入表要在要导入的数据库下,但一般sql文件里面都可能自带有创建数据库的语句)
--------------方式2-----------------
-- -h参数可以省略
mysql -hlocalhost -uroot -p123456 < C:\Users\aj\Desktop\2.sql

6、三大范式(NF:normalform)

范式基本概念:

  • 1NF

    数据库要体现原子性,列中的数据要不可再分

  • 2NF

    一张表只做一件事。不产生局部依赖:对于联合主键而言,非主键的字体不能只完全依赖于其中一个主键,如果只依赖其中一个主键,那么这张表可以拆分成两个表,即原来的表做了“两件事“。

  • 3NF

    数据中的每一列都要与主键直接相关,而不能通过其它字段传递依赖而间接相关。

第二范式和第三范式的区别:

----来源:百度知道

第二范式(bai2NF)和第三范式(3NF)的概念很容易混淆,du区分它们zhi的关键点在于,2NF:非主键列是否完全依dao赖于主键,还是依赖于主键的一部分;3NF:非主键列是直接依赖于主键,还是直接依赖于非主键列。

第二范式(2NF):首先是 1NF,另外包含两部分内容,一是表必须有一个主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。考虑一个订单明细表OrderDetail其属性如下: (OrderID,ProductID,UnitPrice,Discount,Quantity,ProductName)。
因为我们知道在一个订单中可以订购多种产品,所以单单一个OrderID 是不足以成为主键的,主键应该是(OrderID,ProductID)。显而易见 Discount(折扣),Quantity(数量)完全依赖(取决)于主键(OderID,ProductID),而 UnitPrice,ProductName 只依赖于 ProductID。所以 OrderDetail 表不符合 2NF。不符合 2NF的设计容易产生冗余数据。

可以把OrderDetail表拆分为:

OrderDetail(OrderID,ProductID,Discount,Quantity)

Product (ProductID,UnitPrice,ProductName)

来消除原订单表中UnitPrice,ProductName多次重复的情况。
第三范式(3NF):首先是 2NF,另外非主键列必须直接依赖于主键,不能存在传递依赖。即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况。考虑一个订单表Order: (OrderID,OrderDate,CustomerID,CustomerName,CustomerAddr,CustomerCity)主键是(OrderID)。
其中OrderDate,CustomerID,CustomerName,CustomerAddr,CustomerCity
等非主键列都完全依赖于主键(OrderID),所以符合 2NF。

不过问题是CustomerName,CustomerAddr,CustomerCity 直接依赖的是
CustomerID(非主键列),而不是直接依赖于主键,它是通过传递才依赖于主键,所以不符合 3NF。
通过拆分Order为Order(OrderID,OrderDate,CustomerID)和Customer(CustomerID,CustomerName,CustomerAddr,CustomerCity)从而达到 3NF。

范式与性能之间的取舍:

  • 在阿里规范中,关联查询的表不得超过3张表
  • 在商业化的需求中,为了用户体验数据库的性能更加重要
  • 有时会故意增加一些冗余的字段,使多表查询变成单表查询
  • 故意增加一些计算列,从大数据量降低为小数据量。比如增加一个count列,如果要统计数量,直接读取最后一行记录即可。

范式与反范式的优缺点:

范式 反范式
优点 结构合理,避免冗余数据的产生。数据表更新快体积小。 考虑性能,满足需求,减少表的关联
缺点 查询时要对更多的表进行关联查询,性能低。 存在大量数据冗余,维护成本更高

(更新与查询间进行比较)

7、数据库的设计

六、JDBC

1、基本概念

  1. JDBC:Java DataBasse Connectivity 是一套规范,为开发者能如何、更好地访问数据库而设计的一套规范。
  2. 执行原理:用户程序 --> JDBC --> 数据库驱动(不同厂商有不同驱动) --> 数据库
  3. JDBC驱动程序:是对JDBC规范的完整的实现,它的存在在Java程序与数据库系统之间建立了一条通信的渠道。

2、基本语法

步骤:

  • 加载驱动
  • 根据信息建立连接
  • 得到执行语句对象
  • 关闭连接
//加载驱动
Class.forname("com.mysql.jdbc.Driver");
//根据信息,建立连接
String url = "jdbc:mysql://localhost/onlinemall?useSSL=true&useUnicode=true&characterEncoding=utf8";
String user = "roog";
String password = "123456";

Connection con = DriverManager.getConnection(url , user, password);
/** 上面步骤是共性  **/
/********************************************************/
//得到执行语句对象有两种
//第一种,普通sql语句处理对象
String sql = "selece * from `goods` where `price` >= 30";
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(sql);
while (rs.next()) {
    
    操作};

//第二种,预编译语句处理对象
String sql = "selece * from `goods` where goodName = ?";
PreparedStatement pst = con.preparedStatement(sql);
pst.setString(1, "牛奶");
ResultSet rs = pst.executeQuery();
while (rs.next()) {
    
    操作};

/********************************************************/
//释放连接
con.close();
st.close();
pst.close();

3、事务

con.setAutocommit(false);//mysql默认自动提交事务,要先关闭。
                      //同时,关闭自动提交,则相当于自动开启事务
执行代码。。。。。。。

con.commit();
con.rollback();

con.autocommit(true);

4、连接池

全部都要实现DataSource接口

1.DBCP

用到的依赖包:

commons-dbcp2-2.8.0.jar

commons-logging-1.2.jar

commons-pool2-2.9.0.jar

配置文件:

########DBCP配置文件##########
#驱动名
driverClassName=com.mysql.jdbc.Driver
#url
url=jdbc:mysql://localhost:3306/school?useSSL=true&useUnicode=true&characterEncoding=utf8
#用户名
username=root
#密码
password=123456
#初试连接数
initialSize=30
#最大活跃数
maxTotal=30
#最大空闲连接数,用完之后先不释放,看有没有人用,到一定时间后释放
maxIdle=10
#最小空闲连接数
minIdle=5
#最长等待时间(毫秒)
maxWaitMillis=1000
#程序中的连接不使用后是否被连接池回收(该版本要使用removeAbandonedOnMaintenance和removeAbandonedOnBorrow)
#removeAbandoned=true
removeAbandonedOnMaintenance=true
removeAbandonedOnBorrow=true
#连接在所指定的秒数内未使用才会被删除(秒)(为配合测试程序才配置为1秒)
removeAbandonedTimeout=1

Java实现:

        InputStream in = test.class.getClassLoader().getResourceAsStream("dbcp.properties");//从类加载器中拿到配置文件资源
        Properties properties = new Properties();//new一个配置文件实例
        properties.load(in);//加载资源

      //根据配置文件创建工厂
        DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);

     //拿到链接
        Connection con = dataSource.getConnection();
/** 之后的操作和普通jdbc一样  **/

所有的连接池都有DateSource.getConnection()方法

2.C3P0

用到的依赖包:

c3p0-0.9.5.5.jar

mchange-commons-java-0.2.19.jar

xml配置文件:

(也可以在Java里面进行配置,但不建议,因为又发生又偶合)

<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/school?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8</property>
        <property name="user">root</property>
        <property name="password">123456</property>

        <property name="initialPoolSize">10</property>
        <property name="maxIdleTime">30</property>
        <property name="maxPoolSize">100</property>
        <property name="minPoolSize">10</property>
        <property name="maxStatements">200</property><!--最大可创建的statement对象-->
    </default-config>

    <!-- 可以有不同的数据库配置 -->
    <named-config name="intergalactoApp">
        <property name="acquireIncrement">50</property>
        <property name="initialPoolSize">100</property>
        <property name="minPoolSize">50</property>
        <property name="maxPoolSize">1000</property>
    </named-config>
</c3p0-config>

Java代码实现:

        ComboPooledDataSource dataSource = new ComboPooledDataSource();//可以传入参数,代表其它named-config数据库配置
        Connection con = dataSource.getConnection();

猜你喜欢

转载自blog.csdn.net/qq_47234534/article/details/109672786
今日推荐