尚硅谷宋红康MySQL笔记 10-18

是记录,我不会记录的特别详细

第10章 创建和管理表

标识符命名规则

  1. 数据库名、表名不得超过30个字符,变量名限制为29
  2. 只能包含 A–Z, a–z, 0–9, _共63个字符
  3. 数据库名、表名、字段名等对象名中间不要包含空格
  4. 同一个MySQL软件中,数据库不能同名;同一个库中,表不能重名;同一个表中,字段不能重名
    必须保证你的字段没有和保留字、数据库系统或常用方法冲突。如果坚持使用,请在SQL语句中使
    用`(着重号)引起来
  5. 保持字段名和类型的一致性:在命名字段并为其指定数据类型的时候一定要保证一致性,假如数据
    类型在一个表里是整数,那在另一个表里可就别变成字符型了

数据类型

类型类型举例
整数类型TINYINT、SMALLINT、MEDIUMINT、INT(或INTEGER)、BIGINT
浮点类型FLOAT,DOUBLE
定点数类型DECIMAL
位类型BIT
日期时间类型YEAR、TIME、DATE、DATETIME、TIMESTAMP
文本字符串类型CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT
枚举类型ENUM
集合类型SET
二进制字符串类型BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB
JSON类型JSON对象、JSON数组
空间数据类型单值:GEOMETRY、POINT、LINESTRING、POLYGON;
空间数据类型集合:MULTIPOINT、MULTILINESTRING、MULTIPOLYGON、GEOMETRYCOLLECTION

常用的

数据类型描述
INT从-231到231-1的整型数据。存储大小为 4个字节
CHAR(size)定长字符数据。若未指定,默认为1个字符,最大长度255
VARCHAR(size)可变长字符数据,根据字符串实际长度保存,必须指定长度
FLOAT(M,D)单精度,占用4个字节,M=整数位+小数位,D=小数位。 D<=M<=255,0<=D<=30,默认M+D<=6
DOUBLE(M,D)双精度,占用8个字节,D<=M<=255,0<=D<=30,默认M+D<=15
DECIMAL(M,D)高精度小数,占用M+2个字节,D<=M<=65,0<=D<=30,最大取值范围与DOUBLE相同。
DATE日期型数据,格式’YYYY-MM-DD’
BLOB二进制形式的长文本数据,最大可达4G
TEXT长文本数据,最大可达4G

创建和管理数据库

创建数据库

//方式1:创建数据库
CREATE DATABASE 数据库名;
//方式2:创建数据库并指定字符集合
CREATE DATABASE 数据库名 CHARACTER SET 字符集;
//方式3:判断数据库是否已经存在,不存在则创建数据库
CREATE DATABASE IF NOT EXISTS 数据库名;

tips:数据库不能改名,一些工具可以改名,它是先建库,再复制所有表到新库,删除旧库.

使用数据库

  • 查看当前所有数据库
SHOW DATABASES;
  • 查看当前正在使用的数据库
SELECT DATABASE();
  • 查看指定库下所有的表
SHOW TABLES FROM 数据库名;
  • 查看数据库的创建信息
SHOW CREATE DATABASE 数据库名;
SHOW CREATE DATABASE 数据库名\G;//这种在不使用可视化工具的前提下能好看点
  • 使用/切换数据库
USE 数据库名;

修改数据库

  • 更改数据库字符集
    乱码的时候需要用到这条命令
ALTER DATABASE 数据库名 CHARACTER SET 字符集; //字符集就比如utf8,gbk等等

删除数据库

DROP DATABASE 数据库名;
DROP DATABASE IF EXISTS 数据库名;//存在就删,不存在就不执行操作

创建表

  • 方式1
CREATE TABLE [IF NOT EXISTS] 表名(
字段1, 数据类型 [约束条件] [默认值],
字段2, 数据类型 [约束条件] [默认值],
字段3, 数据类型 [约束条件] [默认值],
……
[表约束条件]
);
//IF NOT EXISTS:若存在该表那么就不创建,反之就创建CREATE TABLE emp (
-- int类型
emp_id INT(8) AUTO_INCREMENT primary key,
-- 最多保存20个中英文字符
emp_name VARCHAR(20),
-- 总位数不超过15位
salary DOUBLE,
-- 日期类型
birthday DATE
);
  • 方式2
    使用AS subquery选项,将创建表和插入数据结合起来
CREATE TABLE table [(column1,column2,...)] AS subquery;CREATE TABLE e1 AS SELECT * FROM employees;
CREATE TABLE e2 AS SELECT * FROM employeees WHERE 1=2;//创建的emp2是空表
CREATE TABLE dept1
AS
SELECT employee_id, last_name, salary*12 ANNSAL, hire_date
FROM employees
WHERE department_id = 80;

查看数据表结构

SHOW CREATE TABLE 表名\G

修改表

这里是指修改表的结构,比如添加/删除/重命名列

添加列

ALTER TABLE 表名 ADD [COLUMN] 字段名 字段类型 [FIRST | AFTER 字段名];

修改列

修改数据类型,长度,默认值和位置

ALTER TABLE 表名 MODIFY [COLUMN] 字段名1 字段类型 [DEFAULT 默认值] [FIRST | AFTER 字段名2]ALTER TABLE dept MODIFY last_name VARCHAR(30);//把last_name列的数据类型改为varchar(30)
ALTER TABLE dept MODIFY salary double(6,2) default 1000;//把salary的默认值改为1000
--重命名列
ALTER TABLE 表名 CHANGE [COLUMN] 列名 新列名 新数据类型;ALTER TABLE dept CHANGE department_name dept_name varchar(15);//把department_name列改为 dept_name varchar(15)ALTER TABLE 表名 DROP [COLUMN] 字段名;
ALTER TABLE dept DROP COLUMN job_id;

重命名表

  • RENAME
RENAME TABLE emp TO emp1;
  • ALTER TABLE
ALTER TABLE dept RENAME [TO] dept1;

删除表

DROP TABLE [IF EXISTS] 数据表1 [,数据表2,..,数据表n];

这玩意不能回滚

清空表

删除表中的所有数据,释放表的存储空间

TRUNCATE TABLE test;

不能回滚

扩展

  • 阿里巴巴 《Java开发手册》之MySQL字段命名
  • 表名,字段名必须使用小写字母或数字。
    如:xiyi_user,xiyi_config,xiyi3_username
  • 表必备字段:id,gmt_create,gmt_modified
    id自增,bigint unsigned,gmt_create表示主动式创建,或者过去分词表示被动更新
  • 表的命名最好遵循“业务名称_表的作用”
    如admin_config
  • 库名尽量与应用名称保持一致

合适的字符存储长度,不但节约数据库表空间、节约索引存储,更重要的是提升检索速度。
正例:无符号值可以避免误存负数,且扩大了表示范围。
在这里插入图片描述

  • 如何理解清空表、删除表等操作需要谨慎?

因为MySQL在执行清空表、删除表操作时候不会有任何的确认提示,万一是误删除怎么办?所以在删除之前需要做一个备份
ALTER TABLE同理,表结构是无法撤销的,如果你添加了一个无关紧要的字段那删除了也不碍事,但是如果删除了一个需要的列,那该列的数据全部丢失,数据无价啊!!!

  • MySQL8新特性—DDL的原子化
    就是DDL操作要么成功要么回滚,并且回滚日志写入到data dictionary数据字典表mysql.innodb_ddl_log(这玩意还是隐藏的,可以通过设置参数,将DDL操作日志打印输出到MySQL错误日志中)
DROP TABLE a,b;//b不存在

然后a,b两个表都没有删除.

第11章 表数据操作之增删改

这个我不会记录的详细

插入数据

  • VALUES的方式添加
INSERT INTO 表名 [(COLUMN1,COLUMN2,...,COLUMNN)]VALUES (VALUE1,VALUE2,...,VALUEN)[,(VALUE1,VALUE2,...,VALUEN)];
INSERT INTO 表名
SET 列名 =,列名 =....

插入多条记录的时候最好选择使用单条INSERT语句的方式插入,如我有一张用户表,username,password,若是大量用户注册会产生如下语句

INSERT INTO `User` VALUES('ABC','ABC'),('ABCD','ABCD'),('ABCDE','ABCED');//这样效率高
INSERT INTO `User` VALUES('ABC','ABC');INSERT INSERT INTO `User` VALUES ('ABCD','ABCD');
INSERT INTO `User` VALUES ('ABCDE','ABCED');
  • 将查询结果插入到表中
    把表A的查询结果插入到表B中,前提是结果集的列与表B的列保持一致(列名,数据类型相同)
    结果集的意思是:

source表有a,b,c,d,e,f,g列,target表有a,b,c列,现在把source表的a,b,c列插入到target表的a,b,c列
从source表中查出来a,b,c三列就是结果集

INSERT INTO target 
SELECT a,b,c
FROM source;

语法格式

INSERT INTO TargetTableName
(tar_column1 [,tar_column2,...,tar_columnn])
SELECT 
(src_column1 [,src_column2,...,src_columnn])
FROM SourceTableName
[WHERE condition];
INSERT INTO emp3
SELECT *
FROM employees
WHERE department_id = 100;INSERT INTO emp4(id,name,salary,commission_pct)
SELECT employee_id,last_name,salary,commission_pct
FROM employees
WHERE job_id LIKE '%REP%';

更新数据

语法

UPDATE table_name
SET column1 = value1 [,column2 = value2,...,columnn = valuen ] [WHERE condition];

这里记录一下更新多表数据

//下面的是SQL92语法
UPDATE table1 alias1,table2 alias2 SET COLUMN1 = VALUE1 [,COLUMN2=VALUE2,...,COLUMNN=VALUEN]
WHERE JoinCondition; 
//下面的是SQL99语法
UPDATE table1 alias1 [INNER | LEFT |RIGHT] JOIN table2 alias2 ON JoinCondition SET COLUMN1 = VALUE1 [,COLUMN2=VALUE2,...,COLUMNN=VALUEN];

删除数据

语法

DELETE FROM TableName [WHERE condition];

删除多表记录

//SQL92语法
DELETE Table1_alias,Table2_alias FROM Table1 alias1,Table2 alias2 WHERE JoinCondition;//SQL99
DELETE Table1_alias,Table2_alias FROM Table1 alias1 [INNER | LEFT | RIGHT] JOIN Table2 alias2 ON JoinCondition;

MySQL8新特性:计算列

某一列是通过别的列计算得出的
如创建a表,d,e列,f列是由d列+e列得出的

CREATE TABLE a(id int,d,int,e,int,f int GENERATED ALWAYS AS (d+e) VIRTUAL);

第12章 MySQL数据类型

数据类型这东西,记住几个常用的,不知道选用什么类型的时候去查,查多了就记住了,我是这么干的

MySQL的数据类型

类型类型举例
整数类型TINYINT、SMALLINT、MEDIUMINT、INT(或INTEGER)、BIGINT
浮点类型FLOAT、DOUBLE
定点数类型DECIMAL
位类型BIT
日期时间类型YEAR、TIME、DATE、DATETIME、TIMESTAMP
文本字符串类型CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT
枚举类型ENUM
集合类型SET
二进制字符串类型BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB,JSON类型 JSON对象、JSON数组
空间数据类型单值类型:GEOMETRY、POINT、LINESTRING、POLYGON;
空间数据类型集合类型:MULTIPOINT、MULTILINESTRING、MULTIPOLYGON、GEOMETRYCOLLECTION

常见数据类型的属性:

MySQL关键字含义
NULL数据列可包含NULL值
NOT NULL数据列不允许包含NULL值
DEFAULT默认值
PRIMARY KEY主键
AUTO_INCREMENT自动递增,适用于整数类型
UNSIGNED无符号
CHARACTER SET name指定一个字符集

整数类型

类型介绍

整数类型字节有符号数取值范围无符号数取值范围
TINYINT1-128~1270~255
SMALLINT2-32768~327670~65535
MEDIUMINT3-8388608~83886070~16777215
INT、INTEGER4-2147483648~21474836470~4294967295
BIGINT8-9223372036854775808~92233720368547758070~18446744073709551615

可选属性

  • M

显示宽度,M的取值范围是(0,255),一般需要配合"ZEROFILL"来使用,表示用"0"填满宽度,否则指定显示宽度无效,只对数据宽度小于显示宽度的生效.并且显示宽度与类型可以存储的值范围无关,但是MySQL8以后的整数数据类型不推荐使用显示宽度属性

CREATE TABLE test_int2(
f1 INT,
f2 INT(5),
f3 INT(5) ZEROFILL
);
  • UNSIGNED
    无符号类型,就是非负,适合存储非负整数值,比如年龄
  • ZEROFILL
    用0填充,如果某列是ZEROFILL,那么MySQL自动为当前列添加UNSIGNED属性,填充是在左边填充的(比如显示宽度为3,数据是1,在右边填充0会影响数据)必须和UNSIGNED ZEROFILL一起使用才有意义

适用场景

  • TINYINT :一般用于枚举数据,比如系统设定取值范围很小且固定的场景。
  • SMALLINT :可以用于较小范围的统计数据,比如统计工厂的固定资产库存数量等。
  • MEDIUMINT :用于较大整数的计算,比如车站每日的客流量等。
  • INT、INTEGER :取值范围足够大,一般情况下不用考虑超限问题,用得最多。比如商品编号。
  • BIGINT :只有当你处理特别巨大的整数时才会用到。比如双十一的交易量、大型门户网站点击量、证券公司衍生产品持仓等。

如何选择

主要考虑存储空间可靠性的问题,但必须要确保数据不会超过取值范围,在这个基础上再去考虑如何节省存储空间,因为系统故障产生的成本远远超过增加几个字段存储空间所产生的成本.

浮点类型

可以处理小数,应用范围比整数大

  • FLOAT:单精度浮点数
  • DOUBLE双精度浮点数
    在这里插入图片描述
  • REAL:默认是DOUBLE,如果启用REAL_AS_FLOAT那么就是FLOAT,可以通过下面的语句来启用
SET sql_mode ="REAL_AS_FLOAT";
  • ``Q1:FLOAT 和 DOUBLE 这两种数据类型的区别是啥呢?

所占的字节数不同,一般情况下,所占的字节数越大那么取值范围也大

  • Q2:为什么浮点数类型的无符号数取值范围,只相当于有符号数取值范围的一半,也就是只相当于 有符号数取值范围大于等于零的部分呢?

MySQL 存储浮点数的格式为: 符号(S) 、 尾数(M) 和 阶码(E) 。无论有没有符号,MySQL的浮点数都会存储符号位,浮点数的无符号数的取值范围就是把负数的部分丢掉即保留大于等于0的部分

精度说明

MySQL8.0.17之后的,FLOAT(M,D)和DOUBLE(M,D)的用法官方文档不推荐使用,且FLOAT和DOUBLE的UNSIGNED也不推荐使用了

DOUBLE(M,D)

  • M:精度,整数位+小数位
  • D:小数位
    取值范围: D<=M<=255,0<=D<=30
    不指定的时候按照实际的精度(由硬件和操作系统决定)

超出了怎么办?

  • 整数超过了范围就报错
  • 小数超出了范围分情况
  1. 情况1:若四舍五入后整数部分没有超出范围,就只是警告,但能成功操作并四舍五入删除多余的小数位后保存
  2. 情况二:若四舍五入后整数部分超出了范围,MySQL报错,并拒绝存储

精度误差

他不够精准,是浮点数都有这个问题

CREATE TABLE A(t double(5,2));
INSERT INTO A VALUES(1.12),(2.13),(3.1415);
# 6.3915
SELECT SUM(t)=6.3915 FROM A; //这个的结果是0

在对精度要求特别高的时候,用定点数decimal,不要用浮点数

定点类型

就只有一种,decimal
在这里插入图片描述
存储方式以字符串的方式进行存储,不指定精度和标度的时候,默认是DECIMAL(10,0),当精度超过了定点数类型的精度范围时,MySQL同样会进行四舍五入处理。

位类型:BIT

存储的是二进制,比如1010010

二进制字符串类型长度长度范围占用空间
BIT(M)M1<=M<=64约为(M+7)/8个字节

没有指定M就是一位,这里的M是指二进制的位数,使用SELECT命令查询位字段的时候,可以用BIN()或HEX()函数进行读取,BIN()以二进制的方式展现,HEX()以十六进制的方式展现。b+0查询数据的时候,直接查询存储的十进制数据的值

SELECT f1+0 FROM test;
+--------+
| f1 + 0 |
+--------+
| NULL |
| 23 |
+--------+
2 rows in set (0.00 sec)

日期与时间类型

  • YEAR 类型通常用来表示年
  • DATE 类型通常用来表示年、月、日
  • TIME 类型通常用来表示时、分、秒
  • DATETIME 类型通常用来表示年、月、日、时、分、秒
  • TIMESTAMP 类型通常用来表示带时区的年、月、日、时、分、秒
类型名称字节日期格式最小值最大值
YEAR1YYYY或YY19012155
TIME时间3HH:MM:SS-838:59:59838:59:59
DATE日期3YYYY-MM-DD1000-01-019999-12-03
DATETIME日期时间8YYYY-MM-DD HH:MM:SS1000-01-01 00:00:009999-12-31 23:59:59
TIMESTAMP日期时间4YYYY-MM-DD HH:MM:SS1970-01-01 00:00:00 UTC2038-01-19 03:14:07UTC

TIME可以表示一个时间间隔且可以超过24个小时

YEAR类型

存储格式:

  • 以4位字符串或数字格式表示YEAR类型,格式为YYYY,最小值为1901,最大值为2155
  • 以2为字符串格式表示YEAR类型,最小值为00,最大值为99
    1. 当取值为01~69时表示2001到2069
    1. 当取值为70~99时表示1970~1999
    1. 当取值整数的0或00添加时,是0000年
    1. 取值是日期/字符串的’0’添加,是2000年

但是MySQL5.5.27开始,2位格式的YEAR不推荐使用,YEAR的默认格式就是"YYYY"
从MySQL 8.0.19开始,不推荐使用指定显示宽度的YEAR(4)数据类型。

CREATE TABLE test(
f1 YEAR,
f2 YEAR(4)
);
mysql> DESC test;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| f1 | year(4) | YES | | NULL | |
| f2 | year(4) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
INSERT INTO test
VALUES('2020','2021');
mysql> SELECT * FROM test;
+------+------+
| f1 | f2 |
+------+------+
| 2020 | 2021 |
+------+------+
1 rows in set (0.00 sec)
INSERT INTO test
VALUES('45','71');
INSERT INTO test
VALUES(0,'0');
mysql> SELECT * FROM test;
+------+------+
| f1 | f2 |
+------+------+
| 2020 | 2021 |
| 2045 | 1971 |
| 0000 | 2000 |
+------+------+
3 rows in set (0.00 sec)

DATE类型

只存储日期,没有时间部分,格式位YYYY-MM-DD,需要三个字节的存储空间,在向DATE类型的字段插入数据时,同样需要满足一定的格式条件。

  • YYYY-MM-DD格式或者 YYYYMMDD 格式表示的字符串日期,其最小取值为1000-01-01,最大取值为9999-12-03YYYYMMDD格式会被转化为YYYY-MM-DD格式。
  • YY-MM-DD 格式或者 YYMMDD 格式表示的字符串日期,此格式中,年份为两位数值或字符串满足YEAR类型的格式条件为:当年份取值为0069时,会被转化为20002069当年份取值为70到99时,会被转化为1970到1999
  • 使用 CURRENT_DATE() 或者 NOW() 函数,会插入当前系统的日期。
CREATE TABLE test_date1(
f1 DATE
);
Query OK, 0 rows affected (0.13 sec)
INSERT INTO test_date1
VALUES ('2020-10-01'), ('20201001'),(20201001);
INSERT INTO test_date1
VALUES ('00-01-01'), ('000101'), ('69-10-01'), ('691001'), ('70-01-01'), ('700101'),
('99-01-01'), ('990101');INSERT INTO test_date1
VALUES (000301), (690301), (700301), (990301);
INSERT INTO test_date1
VALUES (CURRENT_DATE()), (NOW());
SELECT *
FROM test_date1;

TIME类型

只表示时间,需要3个字节的存储空间来存储TIME类型的数据,可以使用"HH:MM:SS"格式来表示TIME类型,其中,HH表示小时,MM表示分钟,SS表示秒.

几种不同的格式

  • 使用带有冒号的字符串,比如D HH:MM:SS,HH:MM:SS,HH:MM,D HH:MM,D HH,SS格式都可以,D表示天,范围是0~34,若使用带D的字符串插入到TIME字段中,D会转换为小时,计算格式:D*24+HH;反之就是表示当天的时间,比如12:10表示12:10:00
  • 不带有冒号的字符串或者数字,格式为HHMMSS或者HHMMSS,插入一个非法的字符串或者数字的时候,MySQL会自动转换为00:00:00进行存储,1210,把最右边的解析成秒表示"00:12:10"
  • 使用CURRENT_TIME()或者NOW()会插入当前系统时间

举例:

CREATE TABLE test_time1(
f1 TIME
);
Query OK, 0 rows affected (0.02 sec)
INSERT INTO test_time1
VALUES('2 12:30:29'), ('12:35:29'), ('12:40'), ('2 12:40'),('1 05'), ('45');
INSERT INTO test_time1
VALUES ('123520'), (124011),(1210);
INSERT INTO test_time1
VALUES (NOW()), (CURRENT_TIME());
SELECT * FROM test_time1;

DATETIME类型

在日期时间类型中所占的字节最大,需要8个,格式上就是DATE和TIME的组合,表示为YYYY-MM-DD HH:MM:SS
满足如下格式条件:

  • YYYY-MM-DD HH:MM:SS格式或者YYYYMMDDHHMMSS,最小值为1000-01-01 00:00:00,最大值为9999-12-03 23:59:59
    1. YYYYMMDDHHMMSS格式的数字插入DATETIME类型的字段时,会被转化为YYYY-MM-DD HH:MM:SS格式
  • YY-MM-DD HH:MM:SS 格式或者YYMMDDHHMMSS 格式的字符串插入DATETIME类型的字段时,两位数的年份规则符合YEAR类型的规则,0069表示200020697099表示1970到1999。
  • 使用函数 CURRENT_TIMESTAMP() 和 NOW() ,可以向DATETIME类型的字段插入系统的当前日期和时间
CREATE TABLE test_datetime1(dt DATETIME);
INSERT INTO test_datetime1
VALUES ('2021-01-01 06:50:30'), ('20210101065030');
INSERT INTO test_datetime1
VALUES ('99-01-01 00:00:00'), ('990101000000'), ('20-01-01 00:00:00'),
('200101000000');
INSERT INTO test_datetime1
VALUES (20200101000000), (200101000000), (19990101000000), (990101000000);
INSERT INTO test_datetime1
VALUES (CURRENT_TIMESTAMP()), (NOW());

TIMESTAMP类型

和DATETIME类型相同,都是YYYY-MM-DD HH:MM:SS,4个字节的存储空间,只能存储1970-01-01 00:00:00~2038-01-19 03:14:07 UTC之间的时间,UTC表示世界统一时间

CREATE TABLE test_timestamp(ts TIMESTAMP);
INSERT INTO test_timestamp1
VALUES ('1999-01-01 03:04:50'), ('19990101030405'), ('99-01-01 03:04:05'),
('990101030405');
INSERT INTO test_timestamp1
VALUES ('2020@01@01@00@00@00'), ('20@01@01@00@00@00');
INSERT INTO test_timestamp1
VALUES (CURRENT_TIMESTAMP()), (NOW());
#Incorrect datetime value
INSERT INTO test_timestamp1
VALUES ('2038-01-20 03:14:07');

TIMESTAMP和DATETIME的区别

  • TIMESTAMP的存储空间比较小,表示的范围也比较小
  • TIMESTAMP底层存储的是毫秒值,距离1970-1-1 0:0:0毫秒的毫秒值
  • 两个日期比较大小或日期计算时,TIMESTAMP更方便、更快
  • TIMESTAMP和时区有关
CREATE TABLE temp_time(
d1 DATETIME,
d2 TIMESTAMP
);
INSERT INTO temp_time VALUES('2021-9-2 14:45:52','2021-9-2 14:45:52');
INSERT INTO temp_time VALUES(NOW(),NOW());
mysql> SELECT * FROM temp_time;
+---------------------+---------------------+
| d1 | d2 |
+---------------------+---------------------+
| 2021-09-02 14:45:52 | 2021-09-02 14:45:52 |
| 2021-11-03 17:38:17 | 2021-11-03 17:38:17 |
+---------------------+---------------------+
2 rows in set (0.00 sec)
#修改当前的时区
SET time_zone = '+9:00';
mysql> SELECT * FROM temp_time;
+---------------------+---------------------+
| d1 | d2 |
+---------------------+---------------------+
| 2021-09-02 14:45:52 | 2021-09-02 15:45:52 |
| 2021-11-03 17:38:17 | 2021-11-03 18:38:17 |
+---------------------+---------------------+
2 rows in set (0.00 sec)

开发中经验

用的最多的是DATETIME。注册时间、商品发布时间用时间戳来存储的

SELECT UNIX_TIMESTAMP();

文本字符串类型

MySQL中,文本字符串总体上分为 CHARVARCHARTINYTEXTTEXT MEDIUMTEXTLONGTEXTENUMSET 等类型。``
在这里插入图片描述

CHAR与VARCHAR类型

字符串(文本)类型特点长度长度范围占用存储空间
CHAR(M)固定长度M0<=M<=255M个字节
VARCHAR(M)可变长度M0<=M<=65535(实际长度+1)个字节

CHAR类型

  1. 一般需要指定字符串长度,不指定(M),就是1个字符
  2. 实际长度小于CHAR类型声明的长度,在右侧填充空格,MySQL检索CHAR类型的数据,CHAR类型的字段会去除尾部的空格
  3. 定义CHAR类型字段时,声明的字段长度即为CHAR类型字段所占的存储空间的字节数
CREATE TABLE test_char1(
c1 CHAR,//默认是CHAR(1)
c2 CHAR(5)
);
DESC test_char1;
INSERT INTO test_char1
VALUES('a','Tom');
SELECT c1,CONCAT(c2,'***') FROM test_char1;
INSERT INTO test_char1(c2)
VALUES('a ');
SELECT CHAR_LENGTH(c2)
FROM test_char1;

VARCHAR类型

这个必须要指定长度,检索该类型的数据的时候,会保留数据尾部的空格。VARCHAR类型的字段所占用的存储空间为字符串实际长度加1个字节。

CREATE TABLE test_varchar1(
NAME VARCHAR #错误
);
#Column length too big for column 'NAME' (max = 21845);
CREATE TABLE test_varchar2(
NAME VARCHAR(65535) #错误
);
CREATE TABLE test_varchar3(
NAME VARCHAR(5)
);
INSERT INTO test_varchar3
VALUES('尚硅谷'),('尚硅谷教育');
#Data too long for column 'NAME' at row 1
INSERT INTO test_varchar3
VALUES('尚硅谷IT教育');

如何选择?

类型特点空间上时间上使用场景
CHAR(M)长度固定浪费存储空间效率高存储不大,速度要求高
VARCHAR(M)长度可变节省存储空间效率低非CHAR的情况
  1. 存储比较短的数据,长度固定的数据用CHAR
  2. 存储长度变化幅度比较大的数据的时候用VARCHAR
  3. 具体存储引擎中的情况
  • MyISAM 数据存储引擎和数据列:MyISAM数据表,最好使用固定长度(CHAR)的数据列代替可变长度(VARCHAR)的数据列。这样使得整个表静态化,从而使数据检索更快用空间换时间。
  • MEMORY 存储引擎和数据列:MEMORY数据表目前都使用固定长度的数据行存储,因此无论使用CHAR或VARCHAR列都没有关系,两者都是作为CHAR类型处理的。
    InnoDB 存储引擎,建议使用VARCHAR类型。因为对于InnoDB数据表,内部的行存储格式并没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),而且主要影响性能的因素
    是数据行使用的存储总量,由于char平均占用的空间多于varchar,所以除了简短并且固定长度的,
    其他考虑varchar。这样节省空间,对磁盘I/O和数据存储总量比较好。

TEXT类型

保存和查询数据的时候并没有删除TEXT类型的数据尾部的空格
四种类型,TINYTEXT,TEXT,MEDIUMTEXT,LONGTEXT

文本字符串类型特点长度长度范围占用的存储空间
TINYTEXT小文本、可变长度L0 <= L <= 255 L + 2 个字节
TEXT文本、可变长度L0 <= L <= 65535L + 2 个字节
MEDIUMTEXT中等文本、可变长度L0 <= L <=16777215L + 3 个字节
LONGTEXT大文本、可变长度L0 <= L<= 4294967295(相当于4GB)L + 4 个字节

这玩意不能作为主键,只能采用CHAR(M)或者VARCHAR(M)

开发中经验

主要用来存储比较大的文本端

ENUM类型

设置字段值的时候,ENUM类型只允许从成员中选取单个值,所需要的存储空间由定义ENUM类型时指定的成员个数决定

文本字符串类型长度长度范围占用的存储空间
ENUML1<=L<=655351或2个字节
  • 当ENUM类型包含1~255个成员,需要1个字节的存储空间
  • 当ENUM类型包含256~65535个成员时,需要两个字节的存储空间
INSERT INTO test_enum
VALUES('春'),('秋');
# 忽略大小写
INSERT INTO test_enum
VALUES('UNKNOW');
# 允许按照角标的方式获取指定索引位置的枚举值
INSERT INTO test_enum
VALUES('1'),(3);
# Data truncated for column 'season' at row 1
INSERT INTO test_enum
VALUES('ab');
# 当ENUM类型的字段没有声明为NOT NULL时,插入NULL也是有效的
INSERT INTO test_enum
VALUES(NULL);

SET类型

SET表示一个字符串对象,可以包含0个或多个成员,成员个数的上限为64,设置字段值时,可以取取值范围内的 0 个或多个值。
SET类型包含的成员个数不同时,占用的存储空间也是不同,
在这里插入图片描述

CREATE TABLE test_set(
s SET ('A', 'B', 'C')
);
INSERT INTO test_set (s) VALUES ('A'), ('A,B');
#插入重复的SET类型成员时,MySQL会自动删除重复的成员
INSERT INTO test_set (s) VALUES ('A,B,C,A');
#向SET类型的字段插入SET成员中不存在的值时,MySQL会抛出错误。
INSERT INTO test_set (s) VALUES ('A,B,C,D');
SELECT *
FROM test_set;CREATE TABLE temp_mul(
gender ENUM('男','女'),
hobby SET('吃饭','睡觉','打豆豆','写代码');
INSERT INTO temp_mul VALUES('男','睡觉,打豆豆'); #成功
# Data truncated for column 'gender' at row 1
INSERT INTO temp_mul VALUES('男,女','睡觉,写代码'); #失败
# Data truncated for column 'gender' at row 1
INSERT INTO temp_mul VALUES('妖','睡觉,写代码');#失败
INSERT INTO temp_mul VALUES('男','睡觉,写代码,吃饭'); #成功
);

二进制字符串类型

主要是用来存储一些二进制数据,比如图片的二进制数据,MySQL中支持的二进制字符串类型主要包括BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB 和
LONGBLOB类型。

BINARY与VARBINARY类型

存储的都是二进制字符串
BINARY(M)为固定长度的二进制字符串,M表示最多能存储的字节数,取值范围是0~255个字符,未指定(M)就是1个字节,不足数据宽度的时候在右边填充’\0’补齐指定长度
VARBINARY(M)可变,还需要1或2个字节来存储数据的字节数,总字节数不能超过行的字节长度限制65535.
在这里插入图片描述

CREATE TABLE test_binary1(
f1 BINARY,
f2 BINARY(3),
# f3 VARBINARY,
f4 VARBINARY(10)
);
INSERT INTO test_binary1(f1,f2)
VALUES('a','a');
INSERT INTO test_binary1(f1,f2)
VALUES('尚','尚');#失败
INSERT INTO test_binary1(f2,f4)
VALUES('ab','ab');
mysql> SELECT LENGTH(f2),LENGTH(f4)
-> FROM test_binary1;
+------------+------------+
| LENGTH(f2) | LENGTH(f4) |
+------------+------------+
| 3 | NULL |
| 3 | 2 |
+------------+------------+
2 rows in set (0.00 sec)

BLOB

二进制大对象,容纳可变数量的数据,BLOB类型包括TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB,一般情况下会将图片、音频和视频文件存储到服务器的磁盘上,将路径存储到MySQL当中
在这里插入图片描述

TEXT和BLOB的注意事项

  1. 在执行大量的更新或删除操作的时候,会在数据表中留下很大的空洞,所以为了提高性能,建议定期使用OPTIMIZE TABLE功能对这类表进行碎片整理
  2. 对大文本字段进行模糊查询,MySQL提供了前缀索引。
  3. 把BLOB或TEXT列分离到单独的表中,会减少主表中的碎片

JSON类型

JSON(JavaScript Object Notation)是一种轻量级的 数据交换格式。

CREATE TABLE test_json(
js json
);
INSERT INTO test_json (js)
VALUES ('{"name":"songhk", "age":18, "address":{"province":"beijing",
"city":"beijing"}}');
mysql> SELECT *
-> FROM test_json;

当需要检索JSON类型的字段中数据的某个具体值时,可以使用->或->>符号

SELECT js -> '$.name' AS NAME,js -> '$.age' AS age ,js -> '$.address.province'
AS province, js -> '$.address.city' AS city FROM test_json;

空间类型

这个我实在是记录不下去了,先水一下

空间类型扩展支持地理特征的生成、存储和分析,存储世界上具有位置的任何东西。MySQL使用Geometry(几何)表示所有地理特征

第13章 约束

一些概念

数据完整性(Data Integriry)是指数据的精确性(Accuracy)和可靠性(Reliability)。

约束主要是为了防止数据库中存在不符合语义规定的数据和防止因错误信息的输入输出造成无效操作或错误信息而提出的,主要是从四个方面考虑

  • 实体完整性(Entity Integrity) :同一个表中确保记录的唯一性
  • 域完整性(Domain Integrity) :对于一些字段,取值应该在值域内,如性别只能在男女两者之间选。
  • 引用完整性(Referential Integrity) :例如:员工所在部门,在部门表中要能找到这个部门
  • 用户自定义完整性(User-defined Integrity) :例如密码不能为空,邮箱不能为空

什么是约束

这个了解一下,
约束是表级的强制规定。
可以在创建表时规定约束(通过 CREATE TABLE 语句),或者在表创建之后通过 ALTER TABLE 语句规定
约束。

分类

看导图可能会直接点,图后面有文字版本
在这里插入图片描述

  • 根据约束数据列的限制,约束可分为:
  1. 单列约束:每个约束只约束一列
  2. 多列约束:每个约束可约束多列数据
  • 根据约束的作用范围,约束可分为:
  1. 列级约束:只能作用在一个列上,跟在列的定义后面
  2. 表级约束:可以作用在多个列上,不与列一起,而是单独定义
  • 根据约束起的作用,约束可分为:
  1. NOT NULL 非空约束,规定某个字段不能为空
  2. UNIQUE 唯一约束,规定某个字段在整个表中是唯一的
  3. PRIMARY KEY 主键(非空且唯一)约束
  4. FOREIGN KEY 外键约束
  5. CHECK 检查约束
  6. DEFAULT 默认值约束

查看某个表已有的约束

# information_schema数据库名 
# table_constraint 专门存储各个表的约束
SELECT * FROM information_schema.table_constraints
WHERE table_name = '表名字';

NOT NULL 非空约束

限制某个字段的值不能为空,

特点
  1. 所有的数据类型都可以是NULL
  2. 只能出现在列上,不能组合非空
  3. 可以多列限定非空
    注意:空字符串和0都不等于NULL
  • 添加非空约束
  1. 建表的时候
CREATE TABLE table_name(字段名 数据类型,字段名 数据类型 NOT NULL
);
  1. 建表后
ALTER TABLE 表名称 MODIFY 字段名 数据类型 NOT NULL;
  • 删除非空约束
ALTER TABLE 表名称 MODIFY 字段名 数据类型 NULL;
# 去掉NOT NULL等同于NULL
# 或者
ALTER TABLE 表名称 MODIFY 字段名 数据类型;//默认就是NULL

唯一性约束

确保某个字段的值不能重复,但是可以出现多个NULL

特点
  1. 可以有多个唯一约束
  2. 可以是单列唯一,也可以是组合唯一
  3. 唯一约束允许列值为空
  4. 若不指定约束名就是列名1
  5. MySQL会给唯一约束的列上默认创建一个唯一索引

添加唯一约束

  • 建表时
CREATE TABLE 表名(字段名 数据类型,字段名 数据类型 UNIQUE,字段名 数据类型 UNIQUE KEY,
);
CREATE TABLE 表名(字段名 数据类型,[CONSTRAINT 约束名] UNIQUE KEY(字段名)
);
  • 建表后
# 方式1:
ALTER TABLE 表名称 ADD UNIQUE KEY(字段列表);
# 方式2:
ALTER TANLE 表名称 MODIFY 字段名 字段类型 UNIQUE;

删除唯一约束

  • 添加唯一性约束的列上会自动创建唯一索引
  • 删除唯一约束只能通过删除唯一索引名的方式删除
  • 若未指定索引名称,若是单列就是列名,组合列则默认和排在第一个的列名相同,可自定义约束名字
ALTER TABLE table_name DROP INDEX index_name;
# 查看表的索引
SHOW INDEX FROM table_name;

PRIMARY KEY约束

用来标识表中的一行记录

特点
  1. 等同于 UNIQUE+NOT NULL
  2. 主键名总是为PRIMARY
  3. 主键约束对应着表中的一列或多列,若是多列则这些列不允许为空值,组合的值不允许重复
  4. 一个表只能有一个主键约束
  5. 创建主键约束时,默认会在所在的列或列组合上建立对应的主键索引(若是删除主键约束,主键约束对应的索引就自动删除)
  6. 别修改主键字段的值,可能会破坏数据的完整性
添加
  • 建表时指定主键约束
create table 表名称(
字段名 数据类型 primary key, #列级模式
字段名 数据类型,
字段名 数据类型
);
create table 表名称(
字段名 数据类型,
字段名 数据类型,
字段名 数据类型,
[constraint 约束名] primary key(字段列表) #表级模式
);
  • 建表后添加主键约束
ALTER TABLE 表名称 ADD PRIMARY KEY(字段列表); #字段列表可以是一个字段,也可以是多个字段,如果是多个字段的话,是复合主键
删除
ALTER TABLE 表名称 DROP PRIMARY KEY;

自增列 AUTO_INCREMENT

让指定字段的值自增

特点
  1. 最多有一个
  2. 可顺序增长,可指定初始值
  3. 自增列约束的列必须为键列(主键列,唯一键列),并且列的数据类型必须是整数类型
  4. 若不指定值就是在最大值的基础上加一,若指定就按指定的来
添加
  • 建表时
create table 表名称(
字段名 数据类型 primary key auto_increment,
字段名 数据类型 unique key not null,
字段名 数据类型 unique key,
字段名 数据类型 not null default 默认值,
);
create table 表名称(
字段名 数据类型 default 默认值 ,
字段名 数据类型 unique key auto_increment,
字段名 数据类型 not null default 默认值,,
primary key(字段名)
);
  • 建表后
ALTER TABLE 表名 MODIFY 字段名 数据类型 AUTO_INCREMENT;
删除
ALTER TABLE 表名 MODIFY 字段名 数据类型;#去掉了auto_increment了
MySQL8的新特性 自增变量持久化

这个举例说明比较好点,
下面的专业点

在MySQL 5.7系统中,对于自增主键的分配规则,是由InnoDB数据字典
内部一个 计数器 来决定的,而该计数器只在 内存中维护 ,并不会持久化到磁盘中。当数据库重启时,该计数器会被初始化。

这个是我自己复述的,有点啰嗦
MySQL8以前的版本是把当前自增列的最大值放在内存的一块区域,每次自增的时候去读取那块区域的值,在此基础上加一,若MySQL服务重启,内存被操作系统回收掉了,那么再次插入记录,自增列的值就是插入之前的最大值+1,MySQL8以后的版本是把自增列的最大值好像是放在文件里,这样重启服务也不碍事
看例子吧:

CREATE TABLE test(
id INT PRIMARY KEY AUTO_INCREMENT;
);
INSERT INTO test VALUES(0),(0),(0);
# 查询数据
/*
| id |
+----+
| 1 |
| 2 |
| 3 |
*/
#删除id=3的记录
DELETE FROM test WHERE id = 3;
# 再次插入空值
INSERT INTO test VALUES (0);
# 再次查询
/*
| id |
+----+
| 1 |
| 2 |
| 4 |
*/
# 删除id=3的记录,再次插入的时候并不是在现有id列的最大值的基础上实现+1
# 删除id =4的
DELETE FROM test WHERE id =4;
#重启服务,插入空值
#Windows 是net restart MySQL80
#linux是 systemctl restart mysql
INSERT INTO test VALUES(0);
# 再次查询
/*
| id |
+----+
| 1 |
| 2 |
| 3 |
*/

MySQL8以后的不一样,还是按照以上的操作,但是最后一步的结果是

| id |
+----+
| 1 |
| 2 |
| 3 |
| 5 |

自增变量持久化了
MySQL 8.0将自增主键的计数器持久化到 重做日志 中。每次计数器发生改变,都会将其写入重做日志
中。如果数据库重启,InnoDB会根据重做日志中的信息来初始化计数器的内存值。

FOREIGN KEY 约束

这个阿里巴巴的文档中写的是不要使用这个,但是你要从应用的层面去完成FOREIGN KEY的效果

限定某个表的字段的引用完整性,这个举个例子比较好点,在学校填一些信息的时候,会收集你是那个班的,你不能填一个不存在的班级。

主表和从表/父表和子表

主表(父表):被引用的表,被参考的表,就是上面例子的班级名称
从表(子表):引用别人的表,参考的表,就是上面例子中的存放收集信息的表

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/106857.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

群晖 NAS WebDAV服务手机ES文件浏览器远程访问【无公网IP内网穿透】

&#x1f4f1; iOS开发上架主页 在强者的眼中&#xff0c;没有最好&#xff0c;只有更好。我们是移动开发领域的优质创作者&#xff0c;同时也是阿里云专家博主。 ✨ 关注我们的主页&#xff0c;探索iOS开发的无限可能&#xff01; &#x1f525;我们与您分享最新的技术洞察和实…

QT5.12.12通过ODBC连接到GBase 8s数据库(CentOS)

本示例使用的环境如下&#xff1a; 硬件平台&#xff1a;x86_64&#xff08;amd64&#xff09;操作系统&#xff1a;CentOS 7.8 2003数据库版本&#xff08;含CSDK&#xff09;&#xff1a;GBase 8s V8.8 3.0.0_1 为什么使用QT 5.12.10&#xff1f;该版本包含QODBC。 1&#…

探索AIGC人工智能(Midjourney篇)(二)

文章目录 利用Midjourney进行LOGO设计 用ChatGPT和Midjourney的AI绘画&#xff0c;制作儿童绘本故事 探索Midjourney换脸艺术 添加InsightFaceSwap机器人 Midjourney打造专属动漫头像 ChatGPT Midjourney画一幅水墨画 Midjourney包装设计之美 Midjourney24节气海报插画…

Vue3.0极速入门- 目录和文件说明

目录结构 以下文件均为npm create helloworld自动生成的文件目录结构 目录截图 目录说明 目录/文件说明node_modulesnpm 加载的项目依赖模块src这里是我们要开发的目录&#xff0c;基本上要做的事情都在这个目录里assets放置一些图片&#xff0c;如logo等。componentsvue组件…

matlab使用教程(20)—插值基础

1.网格和散点样本数据 插值是在位于一组样本数据点域中的查询位置进行函数值估算的方法。函数值是根据最接近查询点的样本数据点计算的。MATLAB 根据样本数据的结构&#xff0c;可以执行两种插值。样本数据可以形成网格&#xff0c;也可以是分散的。 网格化的样本数据使得插值…

postgresql基于postgis常用空间函数

1、ST_AsGeoJSON 图元转geojson格式 select ST_AsGeoJSON(l.geom) from g_zd l limit 10 2、 ST_Transform 坐标转换 select st_transform(l.shape, 3857) from sde_wf_cyyq l limit 10select st_astext(st_transform(l.shape, 3857)) from sde_wf_cyyq l limit 103、st_aste…

美团增量数仓建设新进展

摘要&#xff1a;本文整理自美团系统研发工程师汤楚熙&#xff0c;在 Flink Forward Asia 2022 实时湖仓专场的分享。本篇内容主要分为四个部分&#xff1a; 建设背景核心能力设计与优化业务实践未来展望 点击查看原文视频 & 演讲PPT 一、美团增量数仓的建设背景 美团数仓架…

Win系统设置开机自启项及自定义自启程序

Win系统设置开机自启项及自定义自启程序 分用户自启动和系统自启动两种形式&#xff1a; 1. 用户自启动目录&#xff1a;C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup 用快速键打开&#xff1a; Win键R键&#xff0c;输入shell:…

高并发编程-3. Amdahl(阿姆达尔)定律与Gustafson定律

此文章为笔记&#xff0c;为阅读其他文章的感受、补充、记录、练习、汇总&#xff0c;非原创&#xff0c;感谢每个知识分享者。 前言 有关为什么要使用并行程序的问题前面已经进行了简单的探讨。总的来说&#xff0c;最重要的应该是处于两个目的。 第一&#xff0c;为了获得更…

Git+Gitee使用分享

GitGitee快速入门 创建仓库 ​ ​ ​ 初始化本地仓库 验证本地git是否安装好 打开cmd窗口&#xff0c;输入git ​ 这样就OK。 Git 全局设置:(只需要设置一次) 这台电脑如果是第一次使用git&#xff0c;就需要这样初始化一下&#xff0c;这样才知道是谁提交到仓库了。 git confi…

centos安装MySQL 解压版完整教程(按步骤傻瓜式安装

一、卸载系统自带的 Mariadb 查看&#xff1a; rpm -qa|grep mariadb 卸载&#xff1a; rpm -e --nodeps mariadb-libs-5.5.68-1.el7.x86_64 二、卸载 etc 目录下的 my.cnf 文件 rm -rf /etc/my.cnf 三、检查MySQL是否存在 有则先删除 #卸载mysql服务以及删除所有mysql目录 #没…

LeetCode--HOT100题(42)

目录 题目描述&#xff1a;108. 将有序数组转换为二叉搜索树&#xff08;简单&#xff09;题目接口解题思路代码 PS: 题目描述&#xff1a;108. 将有序数组转换为二叉搜索树&#xff08;简单&#xff09; 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xf…

4.17 如何基于 UDP 协议实现可靠传输?

目录 QUIC 是如何实现可靠传输的&#xff1f; Packet Header QUIC Frame Header QUIC 是如何解决 TCP 队头阻塞问题的&#xff1f; 什么是TCP对头阻塞问题&#xff1a; HTTP/2 的队头阻塞: 没有队头阻塞的 QUIC QUIC 是如何做流量控制的&#xff1f; QUIC 实现流量控制…

[C#][原创]操作注册表一些注意点

C#注册表只需要引入 using Microsoft.Win32; C#注册表操作都是通过2个类Registry和RegistryKey进行所有操作。但是有些基本注意事项经常忘记&#xff0c;不常用就很容易忘记。 第一&#xff0c;打开注册表&#xff0c;第2个bool参数问题&#xff1a; RegistryKey key Regi…

DDR PHY

1.ddr phy架构 1.pub&#xff08;phy unility block&#xff09; 支持特性&#xff1a; &#xff08;1&#xff09;不支持SDRAM的DLL off mode &#xff08;2&#xff09;数据位宽是以8bit逐渐递增的&#xff08;这样做的目的是因为可能支持16/32/64bit的总线位宽&#xff…

数据分析--统计学知识

描述型统计 描述统计 1.集中趋势 &#xff1a;众数、平均数、分位数 2.离散趋势&#xff1a; 极值&#xff08;max&#xff09;、极差&#xff08;max-min&#xff09;、平均差、方差、标准差、分位差 3.分布&#xff1a;峰泰、偏度 推理型统计 概率分布&#xff1a;离散型…

Java接口(interface)

接口&#xff08;interface&#xff09;明确了描述类被授权了哪些能力&#xff0c;但不会指定具体的方式。实现类&#xff08;implement&#xff09;一个或多个接口。–>使类完成了实现&#xff0c;是一种对于行为规范的准则的抽象。 个体的方法可以在子类中自写展现&#…

c语言练习题33: 判断回⽂字符串

判断回⽂字符串&#xff1a; 题目&#xff1a; 输⼊⼀个字符串&#xff0c;判断这个字符串是否是回⽂字符串&#xff08;字符串的⻓度⼩于等于30&#xff0c;字符串不包含空 格&#xff09;&#xff0c;如果是回⽂字符串输出Yes&#xff0c;如果不是回⽂字符串输出No。 //回…

ServiceManager接收APP的跨进程Binder通信流程分析

现在一起来分析Server端接收&#xff08;来自APP端&#xff09;Binder数据的整个过程&#xff0c;还是以ServiceManager这个Server为例进行分析,这是一个至下而上的分析过程。 在分析之前先思考ServiceManager是什么&#xff1f;它其实是一个独立的进程&#xff0c;由init解析i…

Kotlin协程flow发送时间间隔debounce

Kotlin协程flow发送时间间隔debounce debounce的作用是让连续发射的数据之间间隔起来。典型的应用场景是搜索引擎里面的关键词输入&#xff0c;当用户输入字符时候&#xff0c;有时候&#xff0c;并不希望用户每输入任何一个单字就触发一次后台真正的查询&#xff0c;而是希望…