Mysql初级
关于数据库操作的SQL主要有4个SQL
查看当前有哪些数据库
- 命令如下:
show databases;
(之间至少要有一个空格,并且英文分号结尾)。 - 数据服务器上中系统会自带四个数据库(暂且不讨论,知道就好):
、
创建数据库
- 命令如下:
creat database+ 数据库名;
(数据库名字在一个mysql服务器上要保存唯一)
- 形如上述情况说明创建成功。
如果要让关键字成为数据库名,那么在创建数据库的时候需要给数据库名加上反引号``
另外SQL里面不区分大小写
- 在创建数据库的时候,还需要指定数据库的“字符集”如果不能正确指定字符集,后续想保存中文,就可能会出问题。表示中文的编码方案主要有两个GBK和UTF-8 (UTF-8是目前世界上最流行的编码方式,不仅能表示中文,也可以表示世界上任何一种语言文字)。
- 例如:
creat database 数据库名 charset utf8;
.
- 可以在创建数据库的时候,指定一个简单的条件
IF NOT EXISTS
表示如果不存在就创建,如果存在就啥都不做,
选择数据库
使用 USE
命令选择要操作的数据库。
USE your_database_name;
要删除表中的所有数据但保留表结构,可以使用 DELETE
或 TRUNCATE
命令。以下是两种方法的详细说明:
删除数据库
- 命令如下:
drop database 数据库名
MySQL支持的数据类型
数值类型:
数据类型 | 大小 | 说明 | 对应java类型 |
---|---|---|---|
BIT | M指定位数,默认为1 | 二进制数,M范围从1到64,存储数值范围从0到2^M-1 | 常用Boolean对应BIT,即只能存0和1 |
TINYINT | 1字节 | Byte | |
SMALLINT | 2字节 | Short | |
INT | 4字节 | Integer | |
BIGINT | 8字节 | Long | |
FLOAT(M,D) | 4字节 | 单精度,M指定长度,D指定小数位数。会发生精度丢失 | Float |
DOUBLE(M,D) | 8字节 | Double | |
DECIMAL(M,D) | M/D最大值+2 | 双精度,M指定长度,D指定小数位数。精确数值 | BigDecimal |
NUMERIC | M/D最大值+2 | 和DECIMAL一样 | BigDecimal |
改进点: |
- 使用
decimal
虽然能够比较精确的表示“钱”,但是运算速度比较慢,空间开销更大 - 1.25元 == 125分
- 使用
int
是更好的方法
扩展资料
数值类型可以指定为无符号(unsigned),表示不取负数
1字节(bytes)= 8bit。
对于整型类型的范围:
- 有符号范围:-2^(类型字节数 * 8-1)到2^(类型字节数 * 8 -1)-1,如int是4字节,就
是 − 2 31 -2^{31} −231到 2 31 − 1 2^{31-1} 231−1- 无符号范围:0到2^(类型字节数 * 8)-1,如int就是2^32-1
尽量不使用unsigned,对于int类型可能存放不下的数据,int unsigned同样可能存放不下,与其
如此,还不如设计时,将int类型提升为bigint类型。
字符串类型
数据类型 | 大小 | 说明 | 对应java类型 |
---|---|---|---|
VARCHAR(SIZE) | 0-65,535字节 | 可变长度字符串 | String |
TEXT | 0-65,535字节 | 长文本数据 | String |
MEDIUMTEXT | 0-16,777,215字节 | 中等长度文本数据 | String |
BLOB | 0-65,535字节 | 二进制形式的长文本数据 | byte[] |
varchar(20)
的单位是字符,表示最多表示20个字
日期类型
数据类型 | 大小 | 说明 |
---|---|---|
DATETIME | 8字节 | |
TIMESTAMP | 4字节 |
- 日期在插入或者查询的时候也是需要加上引号,并且格式是
YYYY-MM-DD XX:XX:XX
;后面的具体时间可以省略
查看表操作
查看表结构
- 命令如下:
desc 表名;
此处的desc
的describe
的缩写
创建表
CREATE TABLE table_name (
field1 datatype,
field2 datatype,
field3 datatype
);
可以使用comment增加字段说明
删除表
- 命令如下:
drop table [if exists] 表名;
MySQL的增删改查(CRUD)
CRUD : Create(新增数据), Retrieve(查询数据),Update(修改数据),Delete(删除数据)
新增(create)
单行数据+全列插入
- 命令如下:
insert into 表名 value (值,值,值,...);
这里列出的个数和类型需要和表结构匹配- MySQL中表示字符串可以使用
'
和“
- SQL是”弱类型系统“,经常进行”隐式类型转化“:比如如果表头是
int
类型,而输入了'100'
那么会隐式转化成100
,同样如果表头是Varchar
类型,而输出了0
那么会隐式转化成'0'
- MySQL中表示字符串可以使用
多行数据+全列插入
- 命令如下:
insert into 表名 value (值,值,值,...), (值,值,值,...);
两者有什么区别?
-
MySQL是一个”客户端-服务器“结构的程序
-
插入2条记录,分2个sql完成
-
一次插入2行,一个sql搞定
-
客户端-服务器交互过程中,交互的次数越多,整体开销就越大,花的时间就越长
多行数据+指定列插入
INSERT INTO 表名 (名称, 名称, 名称) VALUES(值, 值, 值),(值, 值, 值);
- value_list 数量必须和指定列数量及顺序一致
插入时间
- 标准格式:
insert into 表名 values ('YYYY-MM-DD HH:MM:SS');
- 插入当前时间:
insert into 表名 values (now());
查询(Retrieve)
查询所有列
- 命令如下;
select * from 表名;
,其中*
为通配符,可以指代所有列- 但是
select * from 表名;
是很危险的操作,一旦数据量达到千万/亿的级别,此时进行select
就会产生大量的硬盘IO和网络IO,把带宽吃满之后,会导致别人无法正常访问数据库!
- 但是
指定查询列
- 命令如下:
select 列名,列名 from 表名;
- 查询的时候手动指定列名,得到的就是和列名相关的
查询的时候指定表达式
列直接进行加减乘除运算
- 类似
select 列名,列名+10 from 表名;
- 但是生成的表只是临时表,数据库本体中的表不会改变
- 但是如果加或者乘的时候超过类型约定的范围不会报错:因为表的类型是对你硬盘上的存储的数据进行制约,但是当前生成的是临时表,此处计算的是临时表的数据,不会影响到硬盘上的数据
起别名
- 命令如下:
select 表达式 as 别名 from 表名;
,当然as
可以省略,但是不建议- 别名只是针对临时表的列名产生修改
去重查询
- 命令如下L:
select distinct 列名, 列名.... from 表名;
- 涉及到的列名必须所有都相同才会触发重复
- 同样,去重都是针对临时表,硬盘上的数据没有任何变化
排序查询
- 查询的时候,指定按照某个列进行排序,也可以指定是升序还是降序
- 命令如下:
select 列名 frome 表名 order by 列名 (desc);
selcet
后面的列名是什么没有影响- 加上
desc
表示降序排列,此处的desc
是descend
的缩写,asc
表示升序,但是默认可以省略 - 如果有一样的情况,那么此时一样的部分排序是无法预测的
order by
后面可以跟很多的列名,多个列之间使用,
分割,先按照第一列排序,如果相同就按照第二列排序,此时就可以预测了
条件查询
- 命令如下:
select 列名 from 表名 where 条件;
- 查询过程中,指定筛选条件,满足条件的就保留,不满足的就跳过
运算符 | 说明 |
---|---|
>, >=, <, <= | 大于,大于等于,小于,小于等于 |
= | 等于,NULL 不安全,例如 NULL = NULL 的结果是 NULL |
<=> | 等于,NULL 安全,例如 NULL <=> NULL 的结果是 TRUE(1) |
!=, <> | 不等于 |
BETWEEN a0 AND a1 | 范围匹配,[a0, a1],如果 a0 <= value <= a1,返回 TRUE(1) |
IN (option, …) | 如果是 option 中的任意一个,返回 TRUE(1) |
IS NULL | 是 NULL |
IS NOT NULL | 不是 NULL |
LIKE | 模糊匹配。% 表示任意多个(包括 0 个)任意字符;_ 表示任意一个字符 |
AND | TRUE(1)多个条件都必须为TRUE(1),结果才是TRUE(1) |
OR | 任意一个条件为TRUE(1),结果才是TRUE(1) |
NOT | 条件为TRUE(1),结果为FALSE(0) |
注意点
where
条件可以使用表达式,但是不能使用别名AND
的优先级高于OR
,在同时使用的时候,需要用()
包裹优先执行的部分。SQL
中的区间是闭区间,and
和betwee
- 查询
null
的时候不能用等于
,而是用where 列名 is (not) null
,或者where 列名 <=> null
或者where 列名 列名 <=> 列名
(这样可以判断两个null
的情况.)
like模糊查询
select * from 表名 where 列名 like “apple%”
- 表示可以匹配以
apple
开头的任何字符(列名需要是和后面查询的类型相同) - 同理
like "%apple”
,表示可以匹配以apple
结尾的任何字符 - 同理
like %apple%
,表示可以匹配以apple
在中间的任何字符
- 表示可以匹配以
select * from 表名 where 列名 like “apple_”
- 表示可以匹配以
apple
开头,后面跟一个字符的字符串(列名需要是和后面查询的类型相同) - 其他同理
- 表示可以匹配以
sql
中不支持正则,只能用%
或者_
来匹配(开发中还是经常使用正则)
分页查询
- 限制一次查询,最多能查到多少个数据
- 命令如下:
select 列名 from 表名 limit N (offset M);
- 表示一次展示几列,从下标为几开始(从0下标开始计算)
- 也可以写成
select 列名 from 表名 N, M
,但是不建议。
修改(update)
修改数据
- 此时就是真正在改硬盘里面的数据了
- 命令如下:
update 表名 set 列名 = 值,列名 等于 值.....
- 同样也是可以搭配
where
,order by
,limit
- 注意,如果不指定任何条件,就会针对所有的行生效,把表全改了
- 进行加减乘除的时候,只能通过
列名 = 列名 +10
类似的操作不能用+=
- 同样也是可以搭配
修改表结构(ALTER TABLE)
在表已经创建之后,如果需要添加、修改或删除列,可以使用 ALTER TABLE
语句。
添加列
ALTER TABLE 表名 ADD (COLUMN) 列名 数据类型 [约束条件];
例如,假设有一个名为 users
的表,现在需要添加一个名为 email
的列,数据类型为 VARCHAR(255)
,可以使用以下语句:
ALTER TABLE users ADD email VARCHAR(255);
修改列
mysql:
ALTER TABLE 表名 MODIFY 列名 新数据类型 [新约束条件];
sql sever:
ALTER TABLE table_name
ALTER COLUMN column_name new_datatype;
例如,假设需要将 users
表中的 email
列的数据类型修改为 VARCHAR(100)
,可以使用以下语句:
ALTER TABLE users MODIFY email VARCHAR(100);
删除列
ALTER TABLE 表名 DROP COLUMN 列名;
例如,假设需要删除 users
表中的 email
列,可以使用以下语句:
ALTER TABLE users DROP COLUMN email;
重命名列
ALTER TABLE 表名 CHANGE 旧列名 新列名 (新数据类型 [新约束条件]);
例如,假设需要将 users
表中的 email
列重命名为 user_email
,可以使用以下语句:
ALTER TABLE users CHANGE email user_email VARCHAR(100);
注意事项
- 添加列:添加列时,新列会添加到表的末尾。如果需要指定列的位置,可以使用
AFTER
或FIRST
关键字。 - 修改列:修改列时,要注意数据类型的兼容性,避免数据丢失。
- 删除列:删除列时,要注意该列是否包含重要数据,避免误删。
添加外键:
ALTER TABLE table_name
ADD CONSTRAINT fk_name FOREIGN KEY (column_name)
REFERENCES other_table(other_column);
示例
-- 添加列
ALTER TABLE users ADD phone VARCHAR(20);-- 修改列
ALTER TABLE users MODIFY phone VARCHAR(15);-- 删除列
ALTER TABLE users DROP COLUMN phone;-- 重命名列
ALTER TABLE users CHANGE email user_email VARCHAR(100);
删除(delete)
在 SQL 中,有两种主要的删除数据的方法:DELETE
和 TRUNCATE
。它们在功能和性能上有一些重要的区别。
使用DELETE
命令
DELETE
命令用于删除表中的特定行或所有行,不会删除表本身。语法如下:
DELETE FROM 表名 WHERE 条件 ORDER BY 子句 LIMIT 子句;
- 条件:指定要删除的记录。如果不写条件,将删除所有行。
- ORDER BY 和 LIMIT:可选,用于指定删除记录的顺序和数量。
注意:DELETE
命令可以删除表中的所有行,但它不会重置自动增量列(如 AUTO_INCREMENT
)。
使用TRUNCATE
命令
TRUNCATE
命令用于快速删除表中的所有行,并会重置自动增量列。它通常比 DELETE
更快,但有一些限制。TRUNCATE
不能触发 DELETE
触发器。
语法如下:
TRUNCATE TABLE 表名;
- 使用
TRUNCATE
时不能添加任何条件或子句。
主要区别
- 速度:
TRUNCATE
比DELETE
更快,因为TRUNCATE
是一种DDL操作,直接重置表的结构,而DELETE
是一种DML操作,需要逐行删除数据。 - 自动增量列:
TRUNCATE
会重置自动增量列(如AUTO_INCREMENT
),而DELETE
不会。 - 触发器:
DELETE
可以触发DELETE
触发器,而TRUNCATE
不能。
删除整个表
注意:DROP
命令将删除表的结构和数据,无法恢复。
DROP TABLE 表名;
适用场景
DELETE
: 适用于需要逐行删除数据,并且可能需要触发触发器的情况。例如,删除某个用户的所有订单记录。性能较低,适用于少量数据或需要条件删除的情况。TRUNCATE
: 适用于需要快速清空表数据,并且不需要触发触发器的情况。例如,清空测试环境中的临时表数据。性能较高,适用于需要快速清空表数据的情况。
注意事项
DELETE
:- 可以带条件,但要注意条件是否正确,避免误删数据。
- 可以触发
DELETE
触发器,但要注意触发器的逻辑。
TRUNCATE
:- 不能带条件,会删除表中所有数据。
- 不会触发
DELETE
触发器,适用于不需要触发器的情况。 - 会重置
AUTO_INCREMENT
,适用于需要重置自增列的情况。
常见错误和解决方法
- 常见错误: 误删数据、触发器逻辑错误、性能问题等。
- 解决方法: 使用事务、备份数据、优化查询条件等。