总结
操作系统
Linux
centos和Ubuntu区别
| centos | Ubuntu | |
|---|---|---|
| 源码基础与支持来源 | 基于Red Hat Enterprise Linux(RHEL)的源代码重新编译,属于RHEL的免费社区版,由社区维护 | 基于Debian发行版,由Canonical公司开发和维护 |
| 更新周期与版本策略 | 每个版本生命周期长达10年,注重长期稳定性,适合生产环境; 2020年后,CentOS转向CentOS Stream(滚动更新开发分支),不再提供传统稳定版 |
每6个月发布一个新版本,每两年发布一个长期支持(LTS)版本,LTS版本提供5年支持 更新速度快,适合需要新特性的开发和测试环境 |
| 软件包管理与生态系统 | 使用RPM包格式,通过yum或dnf管理软件包;软件源较少,依赖EPEL(Extra Packages for Enterprise Linux)扩展仓库 |
使用DEB包格式,通过apt或apt-get管理软件包;软件生态更丰富,官方源和PPA(个人软件包存档)支持更多最新软件 |
| 内核版本与硬件支持 | 通常包含较旧的内核版本,但经过严格测试,稳定性高; 对传统硬件设备支持较好,适合服务器硬件 |
使用最新的内核版本,提供更多新功能和驱动程序支持; 对新型硬件设备支持较好,兼容性强 |
| 用户界面与使用体验 | 默认桌面环境为GNOME,用户接口传统保守; 更适合服务器用户,默认安装的软件较少 |
默认桌面环境为GNOME,用户界面现代化且易于使用; 提供丰富的图形界面工具,适合新手用户 |
| 社区支持与文档资源 | 社区相对较小,但稳定性和可靠性得到更多关注和测试; 文档偏向服务器运维,适合企业用户 |
拥有庞大的社区和活跃的开发人员,用户可以从社区中获取帮助和支持; 官方Wiki和Ask Ubuntu等资源完善,适合初学者 |
| 适用场景 | 适用于企业级服务器、虚拟机、数据库等需要长期稳定的环境; 需要与RHEL兼容的场景,如商业软件认证 |
适用于开发环境、云计算(如AWS/Azure的默认镜像)、桌面用户; 需要快速获取新特性或硬件支持的场景,如Docker/Kubernetes工具链 |
| 安全性与稳定性 | 保守的更新策略和严格的安全审计,适合安全敏感环境; 继承了RHEL的安全机制和策略,安全更新及时 |
安全更新频率较高,能及时应对各种安全威胁; 社区对安全问题的响应积极,会及时发布安全补丁和解决方案 |
| 成本效益 | 作为RHEL的免费克隆版,为用户提供了企业级功能而无需支付订阅费用,降低了运营成本 | 虽然也是免费的,但更注重用户体验和新特性支持,适合需要快速迭代的项目 |
| 总结 | 更适合企业级服务器环境,注重稳定性和长期支持 | 更适合开发环境、云计算和桌面用户,注重用户体验和新特性支持 |
磁盘剩余量
查看磁盘剩余量
[root@wzm ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/vda1 40G 7.1G 31G 19% /
devtmpfs 868M 0 868M 0% /dev
tmpfs 879M 16K 879M 1% /dev/shm
tmpfs 879M 552K 878M 1% /run
tmpfs 879M 0 879M 0% /sys/fs/cgroup
tmpfs 176M 0 176M 0% /run/user/1002
tmpfs 176M 0 176M 0% /run/user/0
查看某个特定目录或文件夹的磁盘使用情况
[root@wzm usr]# du -sh .
2.5G .
[root@wzm /]# du -sh usr
2.5G usr
[root@wzm /]# du -sh home
36K home
防火墙
开启防火墙
systemctl start firewalld.service
查看防火墙状态(只打印防火墙的运行状态)
firewall-cmd --state
# Result:running OR not running
查看防火墙状态(打印详细信息)
systemctl status firewalld.service关闭防火墙
systemctl stop firewalld.service
重启防火墙
systemctl restart firewalld.service
开启指定端口
firewall-cmd --zone=public --add-port=443/tcp --permanent
–zone=public 表示作用域为公共的
–add-port=443/tcp 添加 tcp 协议的端口端口号为 443
–permanent 永久生效,如果没有此参数,则只能维持当前 服 务生命周期内,重新启动后失效;
firewall-cmd --zone=public --add-port=3306/tcp --permanent查看已开放端口
firewall-cmd --list-ports权限
centos / Ubuntu 切换至root账号
# 使用 su 命令(需要知道root密码)
# 密码输入正确后,你会看到终端提示符变为 #,表示当前用户是root
[wzm@localhost ~]$ su -
密码:
上一次登录:二 4月 22 20:45:32 CST 2025pts/0 上
# 直接指定切换到root用户
[wzm@localhost ~]$ su root
密码:
# 使用 sudo 命令(需要当前用户有sudo权限)
# 执行命令后,系统会提示你输入当前用户的密码(而不是root密码)
sudo su -
# 或
sudo -i
centos / Ubuntu 授权相同点
- 权限机制
- 都遵循标准的Linux权限机制,通过用户(User)、组(Group)和其他(Others)三个类别,以及读(r)、写(w)、执行(x)三种基本权限来控制文件和文件夹的访问。
- 使用相同的命令(如
chmod、chown、chgrp)来管理权限。
- 特殊权限位
- 都支持SUID(Set User ID)、SGID(Set Group ID)和粘滞位(Sticky Bit)等特殊权限位。
- 访问控制列表(ACL)
- 都支持ACL(Access Control Lists),允许更细粒度的权限控制。
centos / Ubuntu 授权区别
| centos | Ubuntu | 总结 | |
|---|---|---|---|
| 默认权限设置 | 默认创建的文件权限为 644(用户:rw-,组:r–,其他:r–)默认创建的文件夹权限为 755(用户:rwx,组:r-x,其他:r-x) |
默认创建的文件权限为 664(用户:rw-,组:rw-,其他:r–)默认创建的文件夹权限为 775(用户:rwx,组:rwx,其他:r-x)。 |
Ubuntu默认分配更宽松的权限给组用户,而CentOS默认权限更严格 |
| 权限管理工具 | 更倾向于使用传统的命令行工具(如chmod、chown)进行权限管理 |
除了命令行工具,还提供了图形化工具(如Nautilus文件管理器的属性对话框)来简化权限管理 |
|
| 默认用户组 | 默认用户组通常与用户名相同(如用户user1的默认组为user1) |
默认用户组可能不同,例如第一个用户的默认组可能为sudo或admin |
|
| SELinux(Security-Enhanced Linux) | 默认启用SELinux,提供更严格的安全策略,可能影响文件和文件夹的访问权限 | 默认不启用SELinux,但提供了AppArmor作为替代的安全模块 |
基本权限指令
chmod(修改权限)
chown(修改所有者)
其他
k8s
docker
检查docker状态
systemctl status docker重启docker
systemctl restart docker
service docker restartsystemctl和service区别
基于不同的服务管理工具
systemctl
基于systemd,是现代 Linux 发行版(如 CentOS 7+/RHEL 7+/Ubuntu 15.04+)的默认服务管理工具。
提供更强大的功能,如依赖管理、日志查看、状态监控等。
service
基于传统的 SysVinit 或 Upstart,是较老的服务管理工具。
功能相对简单,仅用于启动、停止、重启服务等基本操作。
Windows
数据库
Oracle
SQL Server
MySQL
centos安装MySQL
查看是否已经安装MySQL
rpm -qa | grep mysql
rpm -e 文件名
获取MySQL 5.7 Community Repository软件包
# 使用wget下载mysql yum源
[root@localhost ~]# wget https://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm
# 由于系统未安装wget,导致命令执行失败
-bash: wget: command not found
# 先通过curl下载工具包
[root@localhost ~]# sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 2523 100 2523 0 0 11367 0 --:--:-- --:--:-- --:--:-- 11364
# 安装wget
[root@localhost ~]# sudo yum install -y wget
# 重新# 使用wget下载mysql yum源
[root@localhost ~]# wget https://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm
安装软件包
[root@localhost ~]# rpm -ivh mysql57-community-release-el7-8.noarch.rpm
安装MySQL服务
cd /etc/yum.repos.d
yum -y install mysql-server
# 如果安装的时候出现公钥尚未安装的问题
# 需导入导入MySQL软件仓库的GPG公钥
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
# 重新执行一下安装服务的命令
yum -y install mysql-server
启动服务、查看状态、设置开机自动启动
# 启动服务
systemctl start mysqld
# 查看状态
systemctl status mysqld
# 设置开机自动启动
systemctl enable mysqld
# 查看进程
ps -ef | grep mysql
查看安装后随机生成的MySQL密码(初始密码)
[root@localhost yum.repos.d]# grep 'password' /var/log/mysqld.log
2025-04-22T13:46:00.894137Z 1 [Note] A temporary password is generated for root@localhost: PW*GZfqL#4gD
2025-04-22T13:49:04.366669Z 3 [Note] Access denied for user 'root'@'localhost' (using password: YES)
2025-04-22T13:52:09.247223Z 8 [Note] Access denied for user 'root'@'localhost' (using password: NO)
[root@localhost yum.repos.d]# grep 'A temporary password' /var/log/mysqld.log
2025-04-22T13:46:00.894137Z 1 [Note] A temporary password is generated for root@localhost: PW*GZfqL#4gD
登录MySQL数据库
mysql -u root -p
修改密码(等级、长度)
# 执行修改验证密码强度等级的命令,将等级设置为LOW
set global validate_password_policy=LOW;
# 设置密码长度为6,设置密码为123456
set global validate_password_length=6;
ALTER USER USER() IDENTIFIED BY '123456';
查看MySQL服务器中的所有数据库
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema | -- 系统信息数据库
| mysql | -- MySQL 系统数据库
| performance_schema | -- 性能监控数据库
| sys | -- 系统对象视图
+--------------------+
4 rows in set (0.00 sec)
查看一下默认的字符集编码
mysql> show variables like '%char%';
+--------------------------------------+----------------------------+
| Variable_name | Value |
+--------------------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
| validate_password_special_char_count | 1 |
+--------------------------------------+----------------------------+
9 rows in set (0.00 sec)
配置远程连接
GRANT ALL PRIVILEGES ON *.* TO root@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
重新加载权限表
FLUSH PRIVILEGES;
配置防火墙后 即可远程访问连接
# 查看防火墙的状态
systemctl status firewalld
# 开放3306端口
firewall-cmd --zone=public --add-port=3306/tcp --permanent
# 重新载入防火墙规则
firewall-cmd --reload
登录MySQL,查看MySQL安装位置
mysql> show variables like 'datadir';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| datadir | /var/lib/mysql/ |
+---------------+-----------------+
1 row in set (0.00 sec)
主从复制
主库
修改配置文件
在该MySQL配置文件中( /etc/my.cnf)添加以下内容:
[mysqld]
log_bin=mysql-bin # 启用二进制日志
server-id=1 # 设置主库唯一ID(必须与从库不同)
binlog_format=ROW # 推荐使用 ROW 格式(可选)
重启
sudo systemctl restart mysqld
创建复制专用用户
-- 登录MySQL,执行:
CREATE USER 'repl_user'@'slave_ip' IDENTIFIED BY 'your_password';
GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'slave_ip';
FLUSH PRIVILEGES;
-- 将 slave_ip 替换为从库 IP,your_password 替换为强密码
获取主库二进制日志状态
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
-- 记录输出结果中的 File(当前日志文件名)和 Position(日志位置),后续配置从库时需要用到
从库
在该MySQL配置文件中( /etc/my.cnf)添加以下内容:
[mysqld]
server-id=2 # 设置从库唯一ID(必须与主库不同)
read_only=ON # 设置从库为只读(可选,但推荐)
重启
sudo systemctl restart mysqld
配置主库连接信息
-- 登录从库 MySQL,执行:
CHANGE MASTER TO
MASTER_HOST='master_ip', -- 主库IP
MASTER_USER='repl_user', -- 复制用户名
MASTER_PASSWORD='your_password', -- 复制用户密码
MASTER_LOG_FILE='mysql-bin.000001', -- 主库日志文件名(从SHOW MASTER STATUS获取)
MASTER_LOG_POS=154; -- 主库日志位置(从SHOW MASTER STATUS获取)
启动复制进程
START SLAVE;验证复制状态
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.216.130
Master_User: hostname
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 154
Relay_Log_File: localhost-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 154
Relay_Log_Space: 531
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 34a7fa39-1f7b-11f0-94fc-000c29ac8626
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
-- 检查以下关键字段:
-- Slave_IO_Running: Yes
-- Slave_SQL_Running: Yes
-- Last_IO_Error: (应为空)
-- Last_SQL_Error: (应为空)
常见问题排查
- 连接失败
- 检查主从库网络连通性:
ping master_ip - 确认防火墙开放端口:默认 3306
- 检查主从库网络连通性:
- 复制延迟
- 检查主库负载:
SHOW PROCESSLIST; - 优化从库硬件或调整
sync_binlog参数。
- 检查主库负载:
- 数据不一致
- 使用
pt-table-checksum工具校验数据一致性。 - 重新同步数据(需停止复制,全量导出导入,再重新配置)。
- 使用
拓展
- 一主多从:
多个从库独立配置,指向同一个主库。 - 链式复制:
A → B → C,B 既是 A 的从库,也是 C 的主库。 - 半同步复制:
通过插件实现,确保至少一个从库接收数据后才提交事务。
其他
常用的聚合函数有哪五种?
count()、sum()、avg()、min()、max()
count():求表的行数或者指定表中某个列的列值行数,null值被忽略
select count(字段) from 表名 --得到该列值的非null值的行数
select count(*) from 表名 --用于统计整个表的行数。任何行,只要有一行非null,则整个表的行数就会被统计上。全为null(不会出现该情况)则不被统计
sum():返回指定数据的和,只能用于数字列,null值被忽略
select sum(salary) from emp --求所有salary的总和
max():返回一列中的最大值,null值被忽略
select max(column_name) from table_name
min():返回一列中的最小值,null值被忽略
select max(column_name) from table_name
avg():返回数值列的平均值,null值被忽略
select avg(salary) as avg_sal from emp
注意事项
- 聚合函数可用于任何有效的表达式
- 聚合函数会忽略空值
- distinct关键字可以与聚合函数一起使用,这样可以在聚合函数的计算中排除重复项
聚合函数
| 聚合函数 | 描述 | 实例 | MySQL | SQL Server |
|---|---|---|---|---|
| AVG() | 返回某列的平均值 | SELECT AVG(column_name) FROM table_name; | 支持 | 支持 |
| COUNT() | 返回某列中的值的数量 | SELECT COUNT(column_name) FROM table_name; | 支持 | 支持 COUNT() 函数,并且提供了额外的选项,如 COUNT_BIG() 用于处理大量数据 |
| MAX() | 返回某列中的最大值 | SELECT MAX(column_name) FROM table_name; | 支持 | 支持 |
| MIN() | 返回某列中的最小值 | SELECT MIN(column_name) FROM table_name; | 支持 | 支持 |
| SUM() | 返回某列值的总和 | SELECT SUM(column_name) FROM table_name; | 支持 | 支持 |
| GROUP_CONCAT() | 在某些数据库系统(如 MySQL)中,将多个行的值组合成一个由分隔符分隔的字符串 | SELECT GROUP_CONCAT(column_name SEPARATOR ‘, ‘) FROM table_name; | 将多个行的值组合成一个字符串 | 没有直接的 GROUP_CONCAT() 函数,可以使用 FOR XML PATH 来实现类似的功能。 |
| STD() / STDDEV() / STDDEV_POP() / STDDEV_SAMP() | 返回某列的总体或样本标准偏差 | SELECT STD(column_name) FROM table_name; | STD() 和 STDDEV() 函数(它们是等价的) | STDDEVP()(总体标准偏差)和 STDDEV()(样本标准偏差) |
| VAR_POP() / VARIANCE_POP() | 返回某列的总体方差 | SELECT VAR_POP(column_name) FROM table_name; | VAR_POP() | VARP()(总体方差) |
| VAR_SAMP() / VARIANCE_SAMP() | 返回某列的样本方差 | SELECT VAR_SAMP(column_name) FROM table_name | VAR_SAMP() | VAR()(样本方差) |
| COVAR_POP() / COVAR_SAMP() | 返回两个列的协方差 | SELECT COVAR_POP(column1, column2) FROM table_name; | 不直接支持 | 支持 |
| CORRELATION() | 返回两个列之间的相关系数 | SELECT CORRELATION(column1, column2) FROM table_name; | 不直接支持 | 不直接支持 |
| PERCENT_RANK() | 返回相对于其他行的行的百分比排名 | SELECT PERCENT_RANK(column_name) OVER (ORDER BY column_name) FROM table_name; | 不直接支持 | 支持 |
| CUME_DIST() | 返回相对位置的累积分布 | SELECT CUME_DIST(column_name) OVER (ORDER BY column_name) FROM table_name; | 不直接支持 | 支持 |
| NTILE() | 将有序分区中的结果行分成指定数量的近似相等的排名组 | SELECT NTILE(4) OVER (ORDER BY column_name) FROM table_name; | 不直接支持 | 支持 |
| LEAD() / LAG() | 返回指定偏移量的行的值,用于分析数据中的趋势 | SELECT LEAD(column_name, 1) OVER (ORDER BY column_name) FROM table_name; SELECT LAG(column_name, 1) OVER (ORDER BY column_name) FROM table_name; | 从8.0 版本开始支持 | 支持 |
| FIRST_VALUE() / LAST_VALUE() | 返回指定窗口帧中的第一个或最后一个值 | SELECT FIRST_VALUE(column_name) OVER (ORDER BY column_name) FROM table_name; SELECT LAST_VALUE(column_name) OVER (ORDER BY column_name) FROM table_name; | 从 8.0 版本开始支持 FIRST_VALUE() 和 LAST_VALUE() 函数 | 支持 |
| GREATEST() / LEAST() | 返回一组值中的最大值或最小值 | SELECT GREATEST(value1, value2, …) FROM table_name; SELECT LEAST(value1, value2, …) FROM table_name; | 支持 | 支持 |
ORDER BY,GROUP BY
Oracle SQL语句组成:
| 数据定义语言(DDL) | 数据操作语言(DML) | 数据查询语言(DQL) | 事物控制语言(TCL) | 数据控制语言(DCL) |
|---|---|---|---|---|
| CREATE(创建命令)、ALTER(修改)命令、DROP(删除)命令等 | INSERT(插入)命令、UPDATE(更新)命令、DELETE(删除)命令、SELECT…FOR UPDATE(查询)等 | 基本查询语句、Order By子句、Group By子句等 | COMMIT(提交)命令、SAVEPOINT(保存点)命令、ROLLBACK(回滚)命令 | GRANT(授权)命令、REVOKE(撤销)命令 |
SELECT
检索所有列
select * from 表名
查询表的总行数,并命名为cnt
select count(*) (as) cnt from 表名(as可加可不加)
select count(主键或其他不为空的字段) (as) cnt from 表名(as可加可不加)
distinct 搜索去重:select distinct [列名1,列名2,…] from [表名]
INSERT
插入记录的方式汇总:
- 普通插入(全字段):INSERT INTO table_name VALUES (value1, value2, …)
- 普通插入(限定字段):INSERT INTO table_name (column1, column2, …) VALUES (value1, value2, …)
- 多条一次性插入:INSERT INTO table_name (column1, column2, …) VALUES (value1_1, value1_2, …), (value2_1, value2_2, …), …
- 从另一个表导入:INSERT INTO table_name SELECT * FROM table_name2 [WHERE key=value]
- 带更新的插入:REPLACE INTO table_name VALUES (value1, value2, …) (注意这种原理是检测到主键或唯一性索引键重复就删除原记录后重新插入)
UPDATE
修改记录的方式汇总:
- 设置为新值:UPDATE table_name SET column_name=new_value [column_name2=new_value2][WHERE column_name3=value3]
- 根据已有值替换:UPDATE table_name SET key1=replace(key1, ‘查找内容’, ‘替换成内容’) [WHERE column_name3=value3]
修改某表某字段,不允许空值
ALTER TABLE 表名
ALTER COLUMN 修改字段名 字段数据类型 NOT NULL
DELETE
删除记录的方式汇总:
- 根据条件删除:DELETE FROM tb_name [WHERE options][ [ ORDER BY fields ] LIMIT n ]
- 全部删除(表清空,包含自增计数器重置):TRUNCATE tb_name
时间差
- TIMESTAMPDIFF(interval, time_start, time_end) 可计算 time_start-time_end 的时间差,单位以指定的 interval 为准,常用可选:
- SECOND 秒
- MINUTE 分钟(返回秒数差除以60的整数部分)
- HOUR 小时(返回秒数差除以3600的整数部分)
- DAY 天数(返回秒数差除以3600*24的整数部分)
- MONTH 月数
- YEAR 年数
关键词:substing, concat, upper
字符串操作
截取
SUBSTRING(column_name, start, length):这将从列的值中提取一个子字符串,从指定的起始位置开始,直到指定的长度
substring(字符串,起始位置,截取字符数)
拼接
CONCAT(string1, string2, …):这会将两个或多个字符串连接成一个字符串
concat(字符串1,字符串2,字符串3,…)
大写
UPPER(expression):这会将字符串表达式转换为大写。
upper(字符串)
小写
LOWER(expression):这会将字符串表达式转换为小写。
SQL语句书写顺序
select -> distinct -> from -> join -> on-> where -> group by -> having -> order by -> limit
SQL语句执行顺序
from -> on -> join -> where -> group by(开始使用select中的别名,后面的语句中都可以使用别名)-> sum、count、max、min、avg -> having -> select -> distinct -> order by -> limit
WHERE不能接聚合函数(MAX、MIN、COUNT、SUM、AVG等);HAVING后可以接聚合函数;
WHERE用在GROUP BY前,先过滤后分组;
HAVING用在GROUP BY之后,先分组后过滤,且使用HAVING一定要用到GRUOP BY,但用到GROUP BY 不一定有HAVING。
DATEDIFF() 是 SQL 中的一个函数,用于计算两个日期之间的差异
DISTINCT关键字
当查询某个列时,使用 DISTINCT 可以确保结果集中该列的值是唯一的;也可以在查询多个列时使用 DISTINCT,此时 DISTINCT 会确保这些列的组合是唯一的。
注意事项
- 性能影响:使用
DISTINCT可能会对查询性能产生影响,特别是在处理大型数据集时。因为数据库需要额外的工作来识别和消除重复的行。 - NULL 值:
DISTINCT会将NULL值视为不同的值。也就是说,如果列中有多个NULL值,DISTINCT会将它们全部返回。 - 与其他 SQL 语句结合:
DISTINCT可以与其他 SQL 语句(如ORDER BY、WHERE等)结合使用,以进一步定制查询结果。 - 不应用于聚合函数:虽然
DISTINCT用于消除重复行,但它不应该与聚合函数(如SUM(),COUNT(),AVG()等)一起用于单个列,因为这会导致错误或不可预测的结果。
Oracle、SQL Server、MySQL SQL语句区别
| MySQL | SQL Server | Oracle | |
|---|---|---|---|
| 字符串连接 | 使用 CONCAT() 函数 |
使用 + 运算符或 CONCAT() 函数 |
使用 ` |
| 自增字段 | 使用 AUTO_INCREMENT 关键字 |
使用 IDENTITY 关键字 |
使用序列(sequence)和触发器(trigger) |
| 分页查询 | 使用 LIMIT 和 OFFSET |
使用 OFFSET 和 FETCH |
使用 ROWNUM 或 FETCH 和 OFFSET(在12c及更高版本中) |
| 日期函数 | 使用 DATE_FORMAT(), NOW(), DATEDIFF() 等 |
使用 FORMAT(), GETDATE(), DATEDIFF() 等 |
使用 TO_DATE(), SYSDATE, MONTHS_BETWEEN() 等 |
| 变量 | 使用 SET 或 SELECT ... INTO 来定义变量 |
使用 DECLARE 来定义变量,并使用 SET 或 SELECT 来赋值 |
使用 DECLARE 来定义变量,并使用 SELECT INTO 来赋值 |
| LIMIT 返回的行数 | 默认允许使用 LIMIT 返回大量行数 |
在较早的版本中,TOP 有一个默认的行数限制(如 1000 行),但在较新的版本中这个限制已被移除 |
没有内置的行数限制,但分页查询可能需要额外的逻辑 |
| 数据类型 | 使用 TINYINT, MEDIUMINT, LONGTEXT 等 |
使用 TINYINT, INT, VARCHAR(MAX) 等 |
使用 NUMBER, VARCHAR2, CLOB |
| 存储过程和函数 | 存储过程和函数的语法和调用方式在每种数据库系统中也有所不同 | 存储过程和函数的语法和调用方式在每种数据库系统中也有所不同 | 存储过程和函数的语法和调用方式在每种数据库系统中也有所不同 |
数据库的三个范式
- 第一范式(1NF):要求数据库表中的每个字段都是原子性的,即不可再分。这意味着每个字段中不能包含多个值或重复的值。如果一个字段包含多个值,应该将其拆分为多个独立的字段。第一范式确保了数据的原子性,消除了数据的重复和冗余。
- 第二范式(2NF):要求数据库表中的非主键字段必须完全依赖于主键。换句话说,非主键字段必须与主键直接相关,而不是间接相关。如果一个表中存在部分依赖关系,即某些字段只依赖于主键的一部分,就需要将这些字段拆分到另一个表中,以确保每个表都只包含相关的数据。第二范式消除了部分依赖,进一步减少了数据的冗余性。
- 第三范式(3NF):要求数据库表中的非主键字段之间不能存在传递依赖关系。传递依赖是指非主键字段依赖于其他非主键字段。如果存在传递依赖,就需要将这些字段拆分到另一个表中,以消除冗余和数据不一致性。第三范式消除了传递依赖,使得数据结构更加清晰和稳定。
这三个范式的设计目的是确保数据库的简洁性、结构明晰性以及数据的一致性。遵循这些范式可以提高数据库的性能和可维护性,减少数据的冗余和不一致性。然而,需要注意的是,在某些特定场景下,为了优化查询性能或其他原因,可能会选择违反这些范式。因此,在实际应用中,需要根据具体业务需求和数据特点来权衡和选择合适的设计方案。
中间件
Tomcat
典型目录结构
├── bin/ # 可执行文件目录,存放启动和关闭脚本
│ ├── startup.sh # 启动脚本(Linux)
│ ├── shutdown.sh # 关闭脚本(Linux)
│ ├── catalina.sh # 核心脚本(Linux)
│ ├── startup.bat # 启动脚本(Windows)
│ ├── shutdown.bat # 关闭脚本(Windows)
│ ├── catalina.bat # 核心脚本(Windows)
│ └── ...
├── conf/ # 配置文件目录,存放所有配置文件,server.xml 是核心配置文件
│ ├── server.xml # 主配置文件
│ ├── web.xml # 全局 Web 应用配置文件
│ ├── context.xml # 上下文配置文件
│ └── tomcat-users.xml # 用户认证配置文件
├── lib/ # 库文件目录,存放 Tomcat 运行所需的 JAR 包
│ ├── *.jar # Tomcat 运行所需的 JAR 包
├── logs/ # 日志文件目录,存放日志文件,包括访问日志和错误日志
│ ├── catalina.out # 主日志文件
│ ├── localhost_access_log.<date>.txt
│ └── ...
├── temp/ # 临时文件目录,通常无需手动管理
├── webapps/ # Web 应用部署目录,支持文件夹、WAR 包或 JAR 包形式
│ ├── ROOT/ # 默认 Web 应用
│ ├── docs/ # 文档应用
│ ├── examples/ # 示例应用
│ └── ...
└── work/ # 工作目录(存放编译后的 JSP 文件,清理后可强制重新编译)安装
下载要求版本的Tomcat
创建目标目录,在目标目录下进行解压操作
tar -zavf apache-tomcat-8.5.93.tar.gz进入bin目录,启动Tomcat
cd /usr/local/tomcat/apache-tomcat-8.5.93/bin ./startup.sh查看Tomcat是否启动
ps -ef | grep tomcat
重启
进入Tomcat的bin文件夹
cd /apache-tomcat/bin关闭Tomcat服务器
./shutdown.sh查看Tomcat是否已关闭
ps -ef | grep tomcat直接杀死Tomcat进程
kill 端口号查看Tomcat是否已关闭
ps -ef | grep tomcat启动Tomcat
./startup.sh进入日志文件夹,打开服务日志
cd logs tail -f ../logs/catalina.out
常见问题
Nginx
典型目录结构
├── conf/ # 存放配置文件,主配置文件为 nginx.conf
│ ├── nginx.conf # 主配置文件
│ ├── conf.d/ # 子配置文件目录(如站点配置)
│ └── mime.types # MIME 类型映射文件
├── html/ # 默认静态文件目录,可自定义为其他路径
│ ├── 50x.html # 错误页面
│ └── index.html # 默认首页
├── logs/ # 存放日志文件,可自定义路径
│ ├── access.log # 访问日志
│ └── error.log # 错误日志
├── sbin/ # 存放 Nginx 可执行文件,如 nginx
│ └── nginx # Nginx 主程序
└── temp/ # 存放临时文件,通常无需手动管理
自定义目录
- 静态资源目录:
/var/www/html - 日志目录:
/var/log/nginx - SSL 证书目录:
/etc/nginx/ssl
启动nginx
sudo nginx
验证nginx配置
# Linux
nginx -t
# 如果配置正确,会输出 syntax is ok 和 test is successful
# Windows
nginx.exe -t
重新加载配置
# 如果 Nginx 已经在运行,可以重新加载配置
# Linux
sudo nginx -s reload
# Windows
nginx.exe -s reload
nginx配置示例
# 全局配置
user nginx;
worker_processes auto;
# worker_processes 1; # 设置 Nginx 的工作进程数,通常设置为 CPU 核心数
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# 用于配置Nginx服务器的事件模型,例如工作进程的并发连接数等。
events {
# 设置每个worker进程的最大连接数,它决定了Nginx的并发能力
# 通常情况下,我们会把 worker 进程数会设置成系统的 cpu 核数(这里要看大家的机器配置而定),这样 worker 进程会分配到各个 cpu 核心上去执行请求处理,真正做到并行处理
worker_connections 1024; # 每个工作进程的最大连接数
}
# HTTP 配置块
# 用于配置HTTP请求的处理,包括HTTP服务器、反向代理、缓存、负载均衡等。
http {
include mime.types; # 加载 MIME 类型文件,用于正确识别文件类型(如 .html、.jpg)
default_type application/octet-stream; # 默认文件类型,当无法识别文件类型时使用
sendfile on; # 启用高效文件传输,减少 CPU 使用
keepalive_timeout 65; # 长连接超时时间,单位为秒
# 定义一个服务器块
# 用于配置虚拟主机,包括监听的端口、域名、SSL证书等。
server {
listen 80; # 监听端口
server_name localhost; # 服务器名称(域名),可设置为 localhost 或具体域名
# 根目录配置
location / {
root /usr/share/nginx/html; # 静态文件根目录
index index.html index.htm; # 默认首页文件
}
# 反向代理示例(可选)
location /api/ {
proxy_pass http://127.0.0.1:8080/; # 将 /api/ 请求转发到后端服务
proxy_set_header Host $host; # 保留原始主机头
proxy_set_header X-Real-IP $remote_addr; # 传递客户端真实 IP
}
# 错误页面配置(可选)
# 指定404出错的错误页面
error_page 404 /404.html;
# 匹配url /,会在html目录下,访问index.html或index.htm文件
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
# 定义一个服务器块(HTTPS,监听 443 端口)
server {
listen 443 ssl; # 启用 SSL
server_name localhost;
# SSL 证书和私钥文件路径
ssl_certificate /etc/nginx/ssl/server.crt; # 替换为你的证书路径
ssl_certificate_key /etc/nginx/ssl/server.key; # 替换为你的私钥路径
# 推荐的 SSL 配置(增强安全性)
ssl_protocols TLSv1.2 TLSv1.3; # 禁用低版本协议
ssl_ciphers HIGH:!aNULL:!MD5; # 使用强加密套件
ssl_prefer_server_ciphers on;
# 根目录配置
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
# 反向代理示例(可选)
location /api/ {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# 错误页面配置(可选)
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}
常见问题
Nginx 无法启动
- 检查配置文件语法是否正确:
nginx -t - 检查端口是否被占用:
netstat -tuln | grep 80
静态文件无法访问
- 确保
root指定的目录存在,并且文件权限正确。
反向代理无效
- 确保后端服务正在运行,并且
proxy_pass的地址正确。