草稿02

发布时间 2023-07-17 09:04:51作者: 辣辣不吃辣

常用关系型数据库

仅针对mysql、sqlserver、oracle、人大金仓、达梦

数据库是一组文件,位于磁盘,用于存储数据

数据字段类型

类型名称 MySQL SQL Server Oracle DM Kingbase
整数类型 tinyint、smallint、mediumint、int或integer、bingint int、tinyint、smallint、bigint integer、number(p,s) s为0 TINYINT、SMALLINT、INTEGER、INT、NUMBER tinyint、smallint、int4、int、integer、bigint、smallserial、serial、bigserial
小数类型 float、double、decimal float、real、numeric、decimal float、real、decimal(p,s)、number(p,s)、double precision float、real、double、number、numeric real、decimal、numeric、double precision
位类型 bit bit number(1)??? bit bit
字符类型 CHAR(255字符)、VARCHAR(65535字符)、TINYTEXT(256bytes)、TEXT(64kb)、MEDIUMTEXT(16M)、LONGTEXT(4G) char(8kb)、varchar(8kb)、text(2G)、nchar(4kb)、nvarcha(4kb)r、ntext(2G) char(2kb)、varchar2(4kb)、nchar(1kb)、nvarchar(2kb)、long(4G) CHAR(4kb)、CHARACTER、VARCHAR(4kb)、TEXT(64kb)、LONGVARCHAR(2G) char(4kb)、varchar(10M)、text(1G)
布尔类型 tinyint(1) tinyint(1) number(1,0) tinyint(1) bool
日期类型 time、date、datetime、timestamp、year time、date、smalldatetime、datetime、datetime2、datetimeoffset date、timestamp tinyint(1) time、date、timestamp、datetime
枚举类型 enum 通过检查约束定义 通过检查约束定义 通过检查约束定义 通过检查约束定义
JSON类型 json(MySQL5.7及以上版本支持) nvrchar 通常用varchar2 (400),varchar2 (32676)或者BLOB来存储,oracle12C及以上,通过检查约束进行定义 字符串 json
集合类型 set 字符串表示 VARRAY 自定义类型 自定义类型
二进制字符类型 BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB BINARY、VARBINARY、IMAGE raw、long raw、blob、clob BLOB、CLOB 自定义类型

 

MySQL

默认用户:root

默认端口:3306

类型 类型举例
整数类型 tinyint、smallint、mediumint、int或integer、bingint
小数类型 float、double、decimal
位类型 bit(M) 1 <= M <= 64
字符类型 CHAR、VARCHAR、TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT
布尔类型 boolean 实际上是tinyint(1)的别名
日期型 time、date、datetime、timestamp、year
枚举类型 enum
JSON类型 json(MySQL5.7及以上版本支持)
集合类型 set
二进制字符串类型 BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB

整型以及对应的属性

计算规则:

一个字节(byte)由8个二进制位(bits)组成,每个二进制位可以表示0或1两个状态。

因此,一个字节可以表示 2^8 种状态,2^8 ==>256个不同的二进制组合

有符号位:数据类型的数据大小范围:-2^(字节数*8-1)~ 2^(字节数*8-1)-1

无符号位:2^8 ==> 0-255

整数类型 字节 有符号数取值范围 无符号数取值范围
TINYINT 1 -128~127 0~255
SMALLINT 2 -32768~32767 0~65535
MEDIUMINT 3 -8388608~8388607 0~16777215
INT、INTEGER 4 -2147483648~2147483647 0~4294967295
BIGINT 8 -9223372036854775808~9223372036854775807 0~18446744073709551615

M

显示宽度,M的取值范围是(0, 255)。如int(5):当数据宽度小于5位的时候在数字前面需要用字符填满宽度。

注:需要配合“ZEROFILL”使用,表示用“0”填满宽度,否则指定显示宽度无效。

CREATE TABLE test_01(
    field_01 INT,
    field_01 INT(5),
    field_02 INT(5) ZEROFILL
)
insert into test_01 values(1,123,123)
​
mysql> select * from test_01;  # 注:可视化工具查看时,0填充被工具处理了
+----------+----------+----------+
| field_01 | field_02 | field_03 |
+----------+----------+----------+
|        1 |      123 |    00123 |
+----------+----------+----------+
​
/*
设置了显示宽度,那么插入的数据宽度超过显示宽度限制,会不会截断或插入失败?
M只是设置显示宽度,不会对插入的数据有任何影响,还是按照类型的实际宽度进行保存,即`显示宽度与类型可以存储的值范围无关`
从MySQL 8.0.17开始,整数数据类型不推荐使用显示宽度属性。
*/

UNSIGNED

无符号类型(非负),所有的整数类型都有一个可选的属性UNSIGNED(无符号属性),无符号整数类型的最小取值为0

CREATE TABLE test_02(
    field_01 INT,
    field_02 INT unsigned
)
​
show create table test_02
​
CREATE TABLE `test_02` (
  `field_01` int(11) DEFAULT NULL, 
  `field_02` int(10) unsigned DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
/*
int类型默认显示宽度为int(11)
无符号int类型默认显示宽度为int(10)
注:MySQL8中不再显式范围
*/
​

ZEROFILL

0填充,(如果某列是ZEROFILL,那么MySQL会自动为当前列添加UNSIGNED属性),如果指定了ZEROFILL只是表示不够M位时,用0在左边填充

show create table test_01
CREATE TABLE `test_01` (
  `field_01` int(11) DEFAULT NULL,
  `field_02` int(5) DEFAULT NULL,
  `field_03` int(5) unsigned zerofill DEFAULT NULL  # 默认添加了unsigned属性
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

char与varchar类型

字符串(文本)类型 特点 长度 长度范围
CHAR(M) 固定长度 M 1 <= M <= 255
VARCHAR(M) 可变长度 M 1 <= M <= 65535
  • char:

    • CHAR(M) 类型一般需要定义字符串长度。如果不指定(M),长度默认是1个字符。数据长度不足声明值时,在尾部自动填充空格

    • 如:char(255),插入时仅插入了'阿'则存储时后面自动填充空格,

  • varchar:

    • 定义时,必须长度M,否则报错。

decimal

decimal(M,D)

(M,D)中 M=整数位+小数位,D=小数位。 D<=M<=255,0<=D<=30。

create table t_test_04 (decimal_01 decimal(5,2))
/*
若存储时
    整数部分超出了精度范围,MySQL就会报错,不允许存这样的值
    小数点部分若超出范围,则进行四舍五入
*/

text类型

在向TEXT类型的字段保存和查询数据时,系统自动按照实际长度存储,

由于实际存储的长度不确定,text类型不支持作为主键

文本字符串类型 特点 长度 长度范围
TINYTEXT 小文本、可变长度 L 0 <= L <= 255
TEXT 文本、可变长度 L 0 <= L <= 65535
MEDIUMTEXT 中等文本、可变长度 L 0 <= L <= 16777215
LONGTEXT 大文本、可变长度 L 0 <= L<= 4294967295(4GB)

二进制字符串类型

BINARY与VARBINARY类型

BINARY和VARBINARY类似于CHAR和VARCHAR,只是存储的是二进制字符串

二进制字符串类型 特点 值的长度
BINARY(M) 固定长度 M (0 <= M <= 255)字节
VARBINARY(M) 可变长度 M(0 <= M <= 65535)字节

BLOB类型

BLOB是一个二进制大对象,可以容纳可变数量的数据。

注:通常不会在MySQL数据库中使用BLOB类型存储大对象数据

 

二进制字符串类型 值的长度 长度范围 占用空间
TINYBLOB L 0 <= L <= 255 字节 L + 1 个字节
BLOB L 0 <= L <= 65535 字节 L + 2 个字节
MEDIUMBLOB L 0 <= L <= 16777215 (相当于16MB) L + 3 个字节
LONGBLOB L 0 <= L <= 4294967295(相当于4GB) L + 4 个字节

日期类型

datetime

格式上为DATE类型和TIME类型的组合,为YYYY-MM-DD HH:MM:SS,存储占8个字节

可使用current_timestamp()now()函数进行插入

timestamp

显示格式与DATETIME类型相同,但存储的时间范围比DATETIME要小很多,只能存储“1970-01-01 00:00:01 UTC”到“2038-01-19 03:14:07 UTC”之间的时间

占4个字节

create table t_test_01 (timestamp_01 timestamp)
​
insert into t_test_01 values('2038-06-07 11:56:31')
​
# SQL 错误 [1292] [22001]: Data truncation: Incorrect datetime value: '2038-06-07 11:56:31' for column 'timestamp_01' at row 1

MySQL主键自增

(1)一个表最多只能有一个自增长列

(2)当需要产生唯一标识符或顺序值时,可设置自增长

(3)自增长列约束的列必须是键列(主键列,唯一键列)

(4)自增约束的列的数据类型必须是整数类型

关键字

auto_increment

INNODB主键不是连续的

自增值保存在内存

自增主键auto_increment默认初始值为1,如果大于max(primary key)+1,在MySQL重启后,会重置auto_increment=max(primary key)+1

CREATE TABLE `t_test_03` (
`mysql_id` int(11) NOT NULL AUTO_INCREMENT,
`mysql_varchar` varchar(30) DEFAULT '默认值',
PRIMARY KEY (`mysql_id`)
) ENGINE=InnoDB AUTO_INCREMENT =100 DEFAULT CHARSET=utf8mb4  # 可以指定初始值

 

create table t_test_01 (
    mysql_id int not null auto_increment primary key,
    mysql_varchar varchar(30)
)
​
# 步骤一:插入4条数据
insert into t_test_01 (mysql_varchar) values('数据库重启前'),('数据库重启前'),('数据库重启前'),('数据库重启前')
+----------+---------------+
| mysql_id | mysql_varchar |
+----------+---------------+
|        1 | 数据库重启前  |
|        2 | 数据库重启前  |
|        3 | 数据库重启前  |
|        4 | 数据库重启前  |
+----------+---------------+
​
# 步骤二:删除id为4的记录
delete from t_test_01 where mysql_id = 4
​
# 步骤三:插入一条数据
insert into t_test_01 (mysql_varchar)values('删除id为4的以后,再插入的')
​
mysql> select * from t_test_01;
+----------+-------------------------+
| mysql_id | mysql_varchar           |
+----------+-------------------------+
|        1 | 数据库重启前              |
|        2 | 数据库重启前              |
|        3 | 数据库重启前              |
|        5 | 除id为4的以后,再插入的     |
+----------+-------------------------+
​
# 步骤四:删除id为5的
delete from t_test_01 where mysql_id = 5
​
# 步骤五:重启数据库以后,再插入一条数据
insert into t_test_01 (mysql_varchar) values('删除id-5重启后插入')
​
mysql> select * from t_test_01;
+----------+-------------------------+
| mysql_id | mysql_varchar           |
+----------+-------------------------+
|        1 | 数据库重启前              |
|        2 | 数据库重启前              |
|        3 | 数据库重启前              |
|        4 | 删除id-5重启后插入         |      # 可以看出,自增是以4开始的,并不是从6开始的
+----------+-------------------------+
​
# 在MySQL8版本以前,对于自增主键的分配规则,是由InnoDB数据字典内部一个`计数器`来决定的,而该计数器只在`内存中维护`,并不会持久化到磁盘中。当数据库重启时,该计数器会被初始化。
​
# MySQL 8.0将自增主键的计数器持久化到redo-log中。每次计数器发生改变,都会将其写入redo-log中。重启的时候依靠redo log恢复重启之前的值
​

MYISALM

MyISAM引擎的子增值是保存在数据文件.myd中的

/*
​
巴拉巴拉...重复以上INNODB的步骤
​
mysql> select * from t_test_02;
+----------+-------------------------+
| mysql_id | mysql_varchar           |
+----------+-------------------------+
|        1 | 数据库重启前              |
|        2 | 数据库重启前              |
|        3 | 数据库重启前              |
|        6 | 删除id-5重启后插入         |
+----------+-------------------------+
​
​
*/

存储引擎:存储文件格式

MYISALM:速度优先,索引也支持 B+tree、锁是表锁

.frm文件:存储表结构

.myd文件:存储表数据

.myi文件:存储索引

同等数据量的数据,从磁盘上获取数据,MyISAM存储引擎速度要快一些

INNODB:事务优先、索引是B+tree、锁是行锁

.frm文件:存储表结构

.bd文件:存储表数据和索引

root@fac859d9d515:/var/lib/mysql/auto_database# ls |grep -e t_test_01
t_test_01.frm
t_test_01.ibd
root@fac859d9d515:/var/lib/mysql/auto_database# ls |grep -e t_test_02
t_test_02.MYD
t_test_02.MYI
t_test_02.frm
​

测试数据

可直接复制,便于测试使用

create

-- 若为5.7以下版本去除josn字段
​
CREATE TABLE `t_test_01` (
  `mysql_id` int(10) NOT NULL AUTO_INCREMENT,
  `mysql_tinyint` tinyint(1) DEFAULT '0' ,
  `mysql_smallint` smallint(20) DEFAULT NULL ,
  `mysql_mediumint` mediumint(20) DEFAULT NULL COMMENT 'mediumint中整数入湖不支持的类型 ',
  `mysql_int` int(10) DEFAULT NULL ,
  `mysql_bigint` bigint(20) DEFAULT NULL COMMENT '极大整数值',
  `mysql_bit` bit(1) DEFAULT NULL COMMENT '接收布尔值',
  `mysql_float` float(6,2) DEFAULT NULL,
  `mysql_decimal` decimal(14,2) DEFAULT NULL ,
  `mysql_double` double(10,5) DEFAULT NULL,
  `mysql_char` char(255) DEFAULT NULL,
  `mysql_varchar` varchar(255) DEFAULT NULL,
  `mysql_tinytext` tinytext COMMENT '短文本字符串',
  `mysql_text` text COMMENT '长文本数据',
  `mysql_mediumtext` mediumtext COMMENT '中等长度文本数据',
  `mysql_longtext` longtext COMMENT '极大文本数据',
  `mysql_date` date DEFAULT NULL COMMENT '年月日 2020-06-07',
  `mysql_time` time DEFAULT NULL COMMENT 'time入湖不支持的类型 如,22:22:22',
  `mysql_datetime` datetime DEFAULT NULL ,
  `mysql_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'YYYY-MM-DD hh:mm:ss',
  `mysql_year` year(4) DEFAULT NULL COMMENT '入湖不支持类型',
  `mysql_tinyblob` tinyblob COMMENT '不超过 255 个字符的二进制字符串',
  `mysql_blob` blob COMMENT '二进制形式的长文本数据',
  `mysql_mediumblob` mediumblob COMMENT '二进制形式的中等长度文本数据',
  `mysql_longblob` longblob COMMENT '二进制形式的极大文本数据',
  `mysql_binary` binary(255) DEFAULT NULL COMMENT '如同CHAR和VARCHAR,不同的是BINARY和VARBINARY的长度是字节长度而不是字符长度',
  `mysql_varbinary` varbinary(255) DEFAULT NULL ,
  `mysql_real` double DEFAULT NULL,
  `mysql_josn` json DEFAULT NULL,
  `mysql_enum` enum('春','夏','秋','冬','unknow') DEFAULT NULL,
  PRIMARY KEY (`mysql_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4;

insert

INSERT INTO delete_test_01 (mysql_tinyint,mysql_smallint,mysql_mediumint,mysql_int,mysql_bigint,mysql_bit,mysql_float,mysql_decimal,mysql_double,mysql_char,mysql_varchar,mysql_tinytext,mysql_text,mysql_mediumtext,mysql_longtext,mysql_date,mysql_time,mysql_datetime,mysql_timestamp,mysql_year,mysql_tinyblob,mysql_blob,mysql_mediumblob,mysql_longblob,mysql_binary,mysql_varbinary,mysql_real,mysql_josn,mysql_enum) VALUES
     (0,32767,36,3893281,99848283905,1,777.99,888.77,555.55555,'刘备','蜀汉','整弓复中之。tinytext','整弓复中之。ttext','整弓复中之。mysql_mediumtext','整弓复中之。mysql_longtext','2022-12-16','17:38:00',(select NOW()) ,'2023-02-08 09:26:41',2022,'YmluYXJ5IGRhdGE=','哈哈','yaya','lala','YmluYXJ5IGRhdGE=',0x61,100.3537,'{"age": 18, "name": "songhk", "address": {"city": "HangZhou", "province": "HangZhou"}}','春');

 

Oracle

默认用户:system

默认端口:1521

类型 类型举例
整数类型 integer、number(p,s) s为0
小数类型 float、number(p,s) s不为0
字符类型 char、varchar2、nchar、nvarchar、后跟的是字节

字符类型

字符串(文本)类型 特点 长度 长度范围 单位
CHAR(n) 固定长度 n 1 <= n <= 2000 字节
VARCHAR2(n) 可变长度 n 1 <= n <= 4000 字节
NCHAR(n) 固定长度 n 1 <= n <= 1000 字符
NVARCHAR2( 可变长度 n 1 <= n <= 2000 字符
  • char 定长字符类型

    • 未达到指定长度时,自动在末尾用空格补全

  • nchar 定长字符类型

    • 定长字符类型,自动在末尾用空格补全

  • varchar2 变长字符类型

    • 未达到指定长度时,不自动补全空格

  • nvarchar2 变长字符类型

    • 未达到指定长度时,不自动补全空格

NUMBER类型

/*
Number 既可以表示数字类型,也可以浮点类型
​
NUMBER(P,S)
P是Precison的缩写,即精度缩写,表示有效数字的位数,最多不能超过38个有效数字
S是Scale的缩写,即标度(小数点位)缩写;表示小数点数字的位数
*/
  • number类型的子类型

    • integer或int是number的子类型,等同于number(38)

    • smallint是number的子类型,等同于number(38)

    • decimal是number(p,s)的子类型,可以使用decimal(p,s),若p,s未指定,等同于number(38)

INTEGER

/*
INTEGER是NUMBER的子类型,等价于NUMBER(38,0),用来存储整数。若插入、更新的数值有小数,则会被四舍五入
*/

float和real类型

  • float(b),数b表示二进制进度,b的取值范围为[1,126],默认为126

  • real是float(b)的子类型,等同于float(63)

long类型与lob大型对象数据类型

Oracle单张表中,仅有一列可以为long或long raw

字符串(文本)类型 特点 存储范围
long 文本类型 2G
long raw 可变长二进制数据 2G
blob 二进制大型对象 4G
clob 字符大型对象 4G
nclob 存储Unicode类型的数据 4G
/*
LONG:存储变长字符串(超长字符串),最多达2G的字节数据(2GB是指2千兆字节,而不是2千兆字符)
LONG RAW:能存储2GB的原始二进制数据,可存放多媒体图像声音等
RAW:用于存储二进制或字符类型数据,必须指定长度。这种类型存储的数据不会发生字符集转换,可存放多美媒体图像声音等
​
限制:
1、一个表中只能包含一个 LONG 类型的列。
2、不能索引LONG类型列、不能将含有LONG类型列的表作聚簇、不能对LONG类型列加约束条件(NULL、NOT NULL、DEFAULT除外),如:关键字列(PRIMARY KEY)不能是 LONG 数据类型。
4、不能在SQL*Plus中将LONG类型列的数值插入到另一个表格中,如insert into …select。
5、不能在SQL*Plus中通过查询其他表的方式来创建LONG类型列,如create table as select。
6、LONG类型列不能用在Select的以下子句中:where、group by、order by,以及带有distinct的select语句中。
7、LONG类型列不能被SQL函数所改变,如:substr、instr。
*/

日期

date、timestamp、以及带时区的时间类型

  • date

    • 存储年月日时分秒,精确到秒

  • timestamp

    • 时间戳,精确到纳秒

  • 区别

    • 都是表示年月日时分秒,但timestamp类型不仅可以保存日期和时间,还能保存 小数位,小数位可以指定0-9,默认为6位 小数位,小数位可以指定0-9,默认为6位

# 获取当前日期和时间
SELECT SYSDATE FROM dual;
SELECT CURRENT_DATE FROM dual;
SELECT CURRENT_TIMESTAMP FROM dual;  # 带时区  2023-06-08 16:50:56.494 +0800
 
​
-- 使用函数to_date(),to_timestamp()将字符串转换为日期格式
​
UPDATE ORACLE_MAP_MSYQL_01 SET ORACLE_DATE  = TO_DATE('2023-05-15','yyyy-mm-dd')
​
UPDATE ORACLE_MAP_MSYQL_01 SET ORACLE_TIMESTAMP  = TO_TIMESTAMP('2023-05-15 18:21:12','yyyy-mm-dd hh24:mi:ss')

oracle创建用户流程

sys/system用户下才有此权限

-- 1、先查询表空间所在的存储位置 
select * from dba_data_files
​
-- 2、创建永久表空间(permanent online) 永久表空间的引号要去除掉
create tablespace '永久表空间名' datafile '文件路径\文件名.dbf' size "空间大小" 15M autoextend on next 10M permanent online;
-- 例:
create tablespace TEST_USER_SPACE datafile '/u01/app/oracle/oradata/test_user_T_SPACE_01.dbf' size 15G autoextend on next 1G permanent online;
​
​
-- 创建用户并指定表空间
create user "用户名" identified by "密码" default tablespace "表空间"
​
-- 例:
create user test_user identified by 123456 default tablespace TEST_USER_SPACE
-- 给用户授予dba权限(创建用户以后要及时分配权限)
grant dba to TEST_CLOUD;

扩大表空间

# 查询表空间是否开启了自动扩展,autoextensible列 yes开启,no未开启
select * from dba_data_files
​
# 开启自动扩展
alter database datafile '/opt/oracle/oradata/SID/logminer_tbs35.dbf' autoextend on next 10G permanent online;
​
# 查询表空间所在位置
SELECT tablespace_name,file_id,file_name,round(bytes / (1024 * 1024), 0) total_space FROM dba_data_files ORDER BY tablespace_name;
​
# 增加文件数量
alter tablespace 表空间名称 add datafile '/opt/oracle/oradata/SID/logminer_tbs17.dbf' size 5G;
​

 

测试数据

可直接复制,便于测试使用

create

CREATE TABLE "T_AUTO_API_01" 
   (    "ORA_NUMBER_38" NUMBER, 
    "ORA_TINYINT" NUMBER(3,0), 
    "ORA_SMALLINT" NUMBER(*,0), 
    "ORA_MEDUIMINT" NUMBER(7,0), 
    "ORA_INT" NUMBER(10,0), 
    "ORA_BIGINT" NUMBER(20,0), 
    "ORA_BOOLEAN" NUMBER(1,0), 
    "ORA_INTGER" NUMBER(*,0), 
    "ORA_DECIMAL" NUMBER(10,3), 
    "ORA_FLOAT" FLOAT(126), 
    "ORA_REAL" FLOAT(63), 
    "ORA_NUMBER_FLOAT" NUMBER(10,3), 
    "ORA_CHAR" CHAR(100), 
    "ORA_VARCHAR" VARCHAR2(255), 
    "ORA_NCHAR" NCHAR(255), 
    "ORA_NARCHAR2" NVARCHAR2(255), 
    "ORA_DATE" DATE, 
    "ORA_TIMESTAMP" TIMESTAMP (6), 
    "ORA_LONG" LONG, 
    "ORA_RAW" RAW(100), 
    "ORA_BLOB" BLOB, 
    "ORA_CLOB" CLOB, 
    "ORA_NCLOB" NCLOB, 
     CONSTRAINT "T_AUTO_API_01_PK" PRIMARY KEY ("ORA_NUMBER_38")
   );

insert

INSERT INTO "T_AUTO_API_01" (
   "ORA_NUMBER_38",
   "ORA_TINYINT",
   "ORA_SMALLINT",
   "ORA_MEDUIMINT",
   "ORA_INT",
   "ORA_BIGINT",
   "ORA_BOOLEAN",
   "ORA_INTGER",
   "ORA_DECIMAL",
   "ORA_FLOAT",
   "ORA_REAL",
   "ORA_NUMBER_FLOAT",
   "ORA_CHAR",
   "ORA_VARCHAR",
   "ORA_NCHAR",
   "ORA_NARCHAR2",
   "ORA_DATE",
   "ORA_TIMESTAMP",
   "ORA_LONG",
   "ORA_RAW",
   "ORA_BLOB",
   "ORA_CLOB",
   "ORA_NCLOB"
) VALUES (
   1,
   127,
   32767,
   9999999,
   2147483647,
   9223372036854775807,
   1,
   1234567890,
   1234.567,
   1.23456,
   1.23456,
   1234.567,
   'Sample Char Value',
   'Sample Varchar Value',
   'Sample NChar Value',
   'Sample NVarchar Value',
   TO_DATE('2023-06-11', 'YYYY-MM-DD'),
   TO_TIMESTAMP('2023-06-11 12:34:56.000000', 'YYYY-MM-DD HH24:MI:SS.FF'),
   'Sample Long Value',
   '73616D706C65205241572076616C7565',
   HEXTORAW('010111'),
   'sdfsd',
   'sdflksh'
);
​

 

SQL Server

默认用户:sa

默认端口:1433

类型 类型举例
整数类型 tinyint、smallint、int、bingint
小数类型 float、real、decimal(p,s)、numeric(p,s)
位类型 bit(M) 1 <= M <= 64
字符类型 char、varchar、nchar、nvachar、text、ntext
布尔类型 boolean 实际上是tinyint(1)的别名
日期型 time、date、smalldatetime、datetime、datetime2、datetimeoffset
货币类型 money、smallmoney
JSON类型 json(SQL Serever2016(13.x及以上版本支持 )
集合类型 set
二进制字符串类型 BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB、LONGBLOB

字符类型

  • char(n)

    • 定长字符串

  • varchar(n)

    • n为存储字符的最大长度,其取值范围是1~8000

  • nchar(n)

    • n个字符的固定长度Unicode字符数据。n值必须在1~4000之间

  • nvarchar(n)

    • 与varchar类似,存储可变长度Unicode字符数据。n值必须在1~4000之间

  • text

  • ntext

货币类型

  • money

    • -922,337,203,685,477.5808 到 922,337,203,685,477.5807

  • smallmoney

    • -214,748.3648 到 214,748.3647

二进制类型

  • binary(n)

    • 长度为n个字节的固定长度二进制数据,其中n是从1~8000的值。存储大小为n个字节。在输入binary值时,必须在前面带0x,可以使用0xAA5代表AA5,如果输入数据长度大于定于的长度,超出的部分会被截断。

  • varbinary(n)

    • 可变长度二进制数据。其中n是从1~8000的值,在存储时实际值的长度使用存储空间.

json类型

CREATE TABLE my_table (
    id INT,
    json_data NVARCHAR(MAX)
);
​
INSERT INTO my_table (id, json_data)
VALUES (1, N'{"name": "John", "age": 30}');
​
SELECT JSON_VALUE(json_data, '$.name') AS name,
       JSON_VALUE(json_data, '$.age') AS age
FROM my_table;

 

日期

  • time

    • 12:35:29.1234567,仅存储时间。精度为 100 纳秒

  • date

    • 仅存储日期。从 0001 年 1 月 1 日 到 9999 年 12 月 31 日。

  • smalldatetime

    • 从 1900 年 1 月 1 日 到 2079 年 6 月 6 日,精度为 1 分钟。

  • datetime

    • 从 1753 年 1 月 1 日 到 9999 年 12 月 31 日,精度为 3.33 毫秒。

  • datetime2

    • 从 1753 年 1 月 1 日 到 9999 年 12 月 31 日,精度为 100 纳秒。

  • datetimeoffset

    • 与 datetime2 相同,外加时区偏移。

测试数据

create

CREATE TABLE t_sql_auto_01 (
    SQL_ID int NOT NULL,
    SQL_BIT bit NULL,
    SQL_SMALLINT smallint NULL,
    SQL_TINYINT tinyint NULL,
    SQL_DECIMAL decimal(38,5) NULL,
    SQL_NUMERIC numeric(38,5) NULL,
    SQL_MONEY money NULL,
    SQL_SMALLINTMONEY smallmoney NULL,
    SQL_FLOAT float NULL,
    SQL_REAL real NULL,
    SQL_DATE date NULL,
    SQL_DATETIME datetime NULL,
    SQL_DATETIME2 datetime2(0) NULL,
    SQL_TIMESTAMP timestamp DEFAULT yyyy-mm-dd hh-mm-ss NULL COMMENT '和Oracle的long类型一样,每个表只能有一个 timestamp 变量',
    SQL_UNIQUEIDENTIFIER uniqueidentifier NULL,
    SQL_TIME time(0) NULL,
    SQL_DATIETIMEOFFSET datetimeoffset NULL,
    SQL_CHAR char(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    SQL_VARCHAR varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    SQL_TEXT text COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    SQL_NCHAR nchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    SQL_NVARCHAR nvarchar(100) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    SQL_NTEXT ntext COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    SQL_BINARY binary NULL,
    SQL_BIGINT bigint NULL,
    SQL_VARBINARY varbinary(100) NULL,
    SQL_IMAGE image NULL,
    CONSTRAINT t_sql_auto_01_PK PRIMARY KEY (SQL_ID)
);

insert

insert select 复制插入时,删除timestamp字段

INSERT INTO t_sql_auto_01 (SQL_ID,SQL_BIT,SQL_SMALLINT,SQL_TINYINT,SQL_DECIMAL,SQL_NUMERIC,SQL_MONEY,SQL_SMALLINTMONEY,SQL_FLOAT,SQL_REAL,SQL_DATE,SQL_DATETIME,SQL_DATETIME2,SQL_UNIQUEIDENTIFIER,SQL_TIME,SQL_DATIETIMEOFFSET,SQL_CHAR,SQL_VARCHAR,SQL_TEXT,SQL_NCHAR,SQL_NVARCHAR,SQL_NTEXT,SQL_BINARY,SQL_BIGINT,SQL_VARBINARY,SQL_IMAGE) VALUES
     (3,0,100,77,100.23450,77.23450,88.9977,99.9977,10.1234,20.1234,'2023-01-09','2023-01-09 17:35:29.123','2023-01-09 17:35:29.000',newid() ,'17:35:29','2023-05-08 12:35:29.1234567 +12:15','SQL_CHAR','SQL_VARCHAR','SQL_CHAadflkada','sfsfsfsafa','sdfsaagfsgasga','sdflkshakldfklasd',0x30,100,0x3031303130313131,0x303130313031);
​

 

达梦(DM)

默认用户:SYSDBA

默认端口:5236

据说DM 99%兼容Oracle

 

字段类型

DM官网数据类型

类型 类型举例
整数类型 tinyint、smallint、int或integer、bingint、number(p,s)/numeric(p,s)s为0
小数类型 float、real、double、decimal、number(p,s)/numeric(p,s)s不为0
位类型 bit(M) 1 <= M <= 64
字符类型 CHAR、VARCHAR、charcter、text、longvarchar
布尔类型 DM8之前不支持
日期型 time、date、datetime、timestamp、以及带时区的日期
二进制字符串类型 binary、varibinary、blob、 clob、imgae、longvarbinary

测试数据

create

创建表时,若不对字段名增加"",则自动转大写

CREATE TABLE "SYSDBA"."dm_t_01"
(
"DM_NUMERIC" NUMERIC(10,0) NOT NULL,
"DM_NUKMBER" NUMBER(10,0),
"DM_INTEGER" INTEGER,
"DM_INT" INT,
"DM_PLS_INTEGER" INTEGER,
"DM_DECIMAL" DECIMAL(10,0),
"DM_DEC" DEC(3,0),
"DM_BIGINT" BIGINT,
"DM_BIT" BIT,
"DM_TINYINT" TINYINT,
"DM_BYTE" BYTE,
"DM_SMALLINT" SMALLINT,
"DM_FLOAT" FLOAT,
"DM_REAL" REAL,
"DM_DOUBLE" DOUBLE,
"DM_CHAR" CHAR(1),
"DM_CHARACTER" CHARACTER(1),
"DM_VARCHAR" VARCHAR(8188),
"DM_TEXT" TEXT,
"DM_LONGVARCHAR" LONGVARCHAR,
"DM_BLOB" BLOB,
"DM_CLOB" CLOB,
"DM_DATE" DATE,
"DM_TIMESTAMP" TIMESTAMP(6),
"DM_DATETIME" DATETIME(6),
NOT CLUSTER PRIMARY KEY("DM_NUMERIC")) STORAGE(ON "MAIN", CLUSTERBTR) ;

insert

INSERT INTO "SYSDBA"."dm_t_01"
(
    "DM_NUMERIC",
    "DM_NUKMBER",
    "DM_INTEGER",
    "DM_INT",
    "DM_PLS_INTEGER",
    "DM_DECIMAL",
    "DM_DEC",
    "DM_BIGINT",
    "DM_BIT",
    "DM_TINYINT",
    "DM_BYTE",
    "DM_SMALLINT",
    "DM_FLOAT",
    "DM_REAL",
    "DM_DOUBLE",
    "DM_CHAR",
    "DM_CHARACTER",
    "DM_VARCHAR",
    "DM_TEXT",
    "DM_LONGVARCHAR",
    "DM_BLOB",
    "DM_CLOB",
    "DM_DATE",
    "DM_TIMESTAMP",
    "DM_DATETIME"
)
VALUES
(
    12345,
    67890,
    123,
    456,
    789,
    54321,
    987,
    1234567890,
    1,
    2,
    1,
    32767,
    3.14,
    2.71,
    1.618,
    'A',
    'B',
    'This is a VARCHAR value',
    'This is a TEXT value',
    'This is a LONGVARCHAR value',
    EMPTY_BLOB(),
    EMPTY_CLOB(),
    CURRENT_DATE,
    CURRENT_TIMESTAMP,
    CURRENT_TIMESTAMP
);
​

人大金仓(KingBase)

默认端口:54321

默认账户:system

字段类型

类型 类型举例
整数类型 tinyint、smallint、int、mediumint、integer、bingint、smallserial、serial、bigserial
小数类型 real、double precision、decimal、numeric
位类型 bit(M) 1 <= M <= 64
字符类型 char、varchar、text、longtext、mediumtext、tinytext
布尔类型 bool
json类型 json
日期型 time、date、datetime、timestamp、以及带时区的日期
二进制大字符串 binary、varibinary、blob、 clob、imgae、longvarbinary

字符类型

  • 整型

    整数类型 字节 有符号数取值范围 无符号数取值范围
    TINYINT 1 -128~127 0~255
    SMALLINT 2 -32768~32767 0~65535
    MEDIUMINT 3 -8388608~8388607 0~16777215
    INT、INTEGER 4 -2147483648~2147483647 0~4294967295
    BIGINT 8 -9223372036854775808~9223372036854775807 0~18446744073709551615
    smallserial 2 1到32767(自动增加的小整数)  
    serial 4 1到2147483647(自动增加的整数)  
    bigserial 8 1到9223372036854775807自动增加的大整数  
  • char

  • varchar

  • text

    • 变长字符串类型。其字符串的长度最大为 1G

  • longtext

    • 变长字符串类型。其字符串的长度最大为 1G

  • mediumtext

    • 变长字符串类型。其字符串的长度最大为 16777215个字符

  • tinytext

    • 变长字符串类型。其字符串的长度最大为 255个字符

测试数据

create

CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy'); -- 先创建枚举类型
​
CREATE TABLE test_table_01 (
    id INT,
    tinyint_col tinyint,
    smallint_col smallint,
    mediumint_col int4,
    integer_col integer,
    int4range_col int4range,
    int8range_col int8range,
    numrange_col numrange,
    bigint_col bigint,
    bool_col bool,
    bit_col bit,
    decimal_col decimal(10,2),
    numeric_col numeric(10,2),
    real_col real,
    double_col double precision,
    smallserial_col smallserial,
    serial_col serial,
    bigserial_col bigserial,
    char_col char(100),
    varchar_col varchar(255),
    text_col text,
    money_col money,
    date_col date,
    time_col time,
    timestamp_col timestamp,
    datetime_col datetime,
    tsrange_col tsrange,
    daterange_col daterange,
    blob_col blob,
    clob_col clob,
    nclob_col nclob,
    bytea_col bytea,
    bit_col_2 BIT VARYING(5),
    point_col point,
    line_col line,
    cidr_col cidr,
    inet_col inet,
    macaddr_col macaddr,
    uuid_col uuid,
    xml_col xml,
    josn_col json,
    enum_col mood  -- 此类型为引用创建好的枚举类型
);

 

insert

INSERT INTO
    test_table_01 (
        id,
        tinyint_col,
        smallint_col,
        mediumint_col,
        integer_col,
        int4range_col,
        int8range_col,
        numrange_col,
        bigint_col,
        bool_col,
        bit_col,
        decimal_col,
        numeric_col,
        real_col,
        double_col,
        char_col,
        varchar_col,
        text_col,
        money_col,
        date_col,
        time_col,
        timestamp_col,
        datetime_col,
        tsrange_col,
        daterange_col,
        blob_col,
        clob_col,
        nclob_col,
        bytea_col,
        bit_col_2,
        point_col,
        line_col,
        cidr_col,
        inet_col,
        macaddr_col,
        uuid_col,
        xml_col,
        josn_col,
        enum_col
    )
VALUES
    (
        1,
        12,
        32767,
        100,
        100,
        '(11,20)',
        '(11,13132132132)',
        '(11.1,22.2)',
        113213213165,
        0,
        '1',
        99.12,
        88.39,
        10.223,
        10.6666,
        'dfsf ',
        'dsfsfs',
        'sdfsfa',
        758.07,
        '2023-03-23',
        '12:04:00',
        '2023-03-23 04:04:54.000',
        '2023-03-23 04:04:54.000',
        '("2022-03-24 11:11:52","2023-03-24 11:11:52")',
        '(2022-03-25,2123-03-24)',
        '0x303130313130',
        '010110',
        '110000111011',
        '0x30313031313031313030',
        '101',
        '(1.0,3.0)',
        '{1.0,2.0,3.0}',
        '192.168.100.128/25',
        '192.168.10.124',
        '8c:ec:4b:5a:a2:ee',
        'cb9c0caf-6712-4d7e-b6e9-1203daf2d2d4',
        '
<root>
  <element1 id="1">
    This is the content of element 1.
  </element1>
  <element2 id="2" color="blue">
    This is the content of element 2.
  </element2>
</root>
',
        '{"key1":"value1","key2":"value2"}',
        'happy'
    );

 

SQL语句区别

表名/字段规范

数据库 表名/字段名 表名规范
MySQL 最多30个字符 1、以字母开头,只能使用A-Z、a-z、0-9、[#$不建议] 2、除了"_" 下划线可以加,其它特殊字符一律不能加。
SQL Server 最多128个字符 同上
Oracle 最多64个字符 规则同上1、2 Oracle在创建表时,表名会自动转大写,Oracle对表名大小写不敏感 如果在定义表名时含有特殊符号,或者用小写字母来定义表名则需要在表名两侧添加双引号
DM 最多128个字符 规则同上1、2
Kingbase 最多128个字符 规则同上1、2

SQL语句

-- 1.sql大小写不敏感
​
select * from t_test_01   <==> SELECT * FROM t_test_01
​
-- 2.mysql、sqlserver语句中可以没有from,oracle必须有,通常结合from dual 来保证语句块的完整性
/*
Oracle的dual表是一个单行单列的虚拟表、常用在没有目标表的Select语句块中
如:MySQL中可以直接通过select进行计算,select 1 + 1,
但在oracle就直接报错:"SQL 错误 [923] [42000]: ORA-00923: 未找到要求的 FROM 关键字"
select 1 +1 as sum_field from dual;
*/
​
-- 3.表名大小写不敏感(前提是按规范创建才行,如Oracle、达梦的表名规范是大写)
create table "test_sex_02" ( -- 如oracle这样创建,则创建出来时小写的,查询时,*大小写敏感*,且查询时候要带双引号去查询
    "id" NUMBER(10,0),
    sex char(5),
    age NUMBER(3,0)
)

精度、标度

create table t_test_01(
    ora_number number(5,2)
)
/*
如上,精度是指数字位数+小数点位数,即精度为5
其中小数点位数也称标度,即标度为2
*/

 

查询数据库版本

# MySQL
select version()
select @@version
​
# SQL Server
select @@version
​
# Oracle、达梦
SELECT * FROM v$version
​
# 人大金仓
select version()

获取系统时间

# MySQL、人大金仓
select now()
​
# SQL Server
select getdate()
​
# Oracle、达梦
select sysdate from dual; 
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;  -- 将date类型转换成字符串

单双引号

Oracle、SQL Server、达梦、人大金仓 中对字段字符类型的值修改必须使用单引号,MySQL对引号没有限制

数据库 引号 示例
MySQL 单双引号都行,没有限制  
Oracle、SQL Server、DM、Kingbase 必须使用单引号 update ora_test_t_01 set ORA_STRING = 'varchar' where ORA_ID = 1
     

union 和 union all

适用这五种关系型数据库

union union all
UNION 操作会对结果去重且排序,全量排序,即对select 语句所包含的所有字段进行排序 union all直接返回合并的结果,不去重也不排序

distinct

适用以上五种关系型数据库

/*
关键字:distinct
1.要放到所有列的前面
2.若跟多个字段,是对所有字段的组合进行去重
select distinct field01,field02 from t_test_02 即:把field01,field02当作一个整体进行去重操作
*/

JDBC连接串的注意事项

问题场景:之前etl是把类似tinyint(1)和number(1,0)统一映射为bool类型,后面又统一映射成integer类型,测试过程中发现,jdbc连接的数据源,以上类型字段映射时依然为bool类型,导致字段映射时匹配不上

# 在jdbc连接串加上如下配置
&tinyInt1isBit=false&transformedBitIsBoolean=false 

执行顺序

 -- 食用所有关系型数据库
    select 
    ...
    from
    ...
    where
    ...
    group by 
    ...
    having
    ...
    order by
    ...
    limit
    ...
​
/*
1.from
2.where
3.group by
4.having
5.select
6.order by 
7.limit,[rownum]
即:
从from某张表中查询数据,先经过where条件筛选出符号条件的数据
对符合条件的数据进行分组
分组之后使用having过滤筛选
select查询
最后排序输出
​
​
1、为什么在写sql语句的时候,聚合函数不能跟在where条件的后面?
2、ordery by后面可以用select field的as别名
从执行可以看出,
1、在where条件的时候,还没有进行分组;所以聚合函数不能直接跟在where子句中使用
2、因为在执行顺序中,先执行select再执行order by,所以order by后面可以用select as别名
*/

案例

/*
案例一:先使用where条件以后再进行分组过滤
    
selct deptno,max(sal) from emp group by deptno having sal > 3000  # 这样先对整张表分组,再判断,效率有点低
​
select deptno,max(sal) from emp where sal > 3000 group by deptno; #先把sal大于3000的过滤出来,再进行分组,已经过滤了一部分数据,再分组就相对效率高点
​
​
案例二:
​
找出每个岗位的平均薪资,要是显示平均薪资大于1500的,除MANAGER岗位职位,要求按照平均薪资降序排
​
select job,avg(sal) as avg_sal from emp group by job having avg(sal) > 1500 and job != 'MANAGER' order by avg_sal desc 
​
select job,avg(sal) as avg_sal from emp where job != 'MANAGER' group by job having avg(sal) > 1500 ordey by avg_sal desc 
​
*/

字段约束(constraint)

sqlserver和oracle、mysql声明约束时,推荐使用constraint关键字声明

约束是保证数据准确性的最后一道屏障,保证了表中的数据有效性

约束分类:

  • 列级约束:只能作用在一个列上,跟在列的定义后面

  • 表级约束:可以作用在多个列上,不与列一起,而是单独定义

--
create table t_test_01(mysql_id int not null primary key auto_increment)

默认约束(default)

给字段指定默认值

CREATE TABLE `t_test_03` (
  `mysql_id` int(11) NOT NULL AUTO_INCREMENT,
  `mysql_varchar` varchar(30) DEFAULT '默认值',
  PRIMARY KEY (`mysql_id`)
) ENGINE=MyISAM

非空约束(not null)

特点

  • 默认,所有的类型的值都可以是NULL,包括INT、FLOAT等数据类型

  • 非空约束只能出现在表对象的列上,只能某个列单独限定非空,不能组合非空

  • 一个表可以有很多列都分别限定了非空

create table test_t_01(my_int int not null) # 列级约束
​
create table test_t_03 (
    my_int int,
    my_int02 int,
    unique (my_int,my_int02)  # 表级约束
)

唯一性约束(unique)

  • 唯一约束可作用在单列或多列上,对于这些列或列组合,唯一约束保证每一行的唯一性

  • 唯一性约束的字段不能重复,但可以为null且允许出现多个空值

特点

  • 同一个表可以有多个唯一约束。

  • 唯一约束可以是某一个列的值唯一,也可以多个列组合的值唯一。

  • 唯一性约束允许列值为空。

  • 在创建唯一约束的时候,如果不给唯一约束命名,就默认和列名相同。

  • MySQL会给唯一约束的列上默认创建一个唯一索引。

create table 表名称(
    字段名  数据类型,
    字段名  数据类型  unique,  
    字段名  数据类型  unique key,   # 列级约束
    字段名  数据类型
);
​
create table 表名称(
    字段名  数据类型,
    字段名  数据类型, 
    [constraint 约束名] unique key(字段名1,字段名2...)   # 表级约束
);

not null 和 unique联合使用

/* 
在MySQL当中,如果一个字段同时被not null和unique约束的话,该字段自动会设置成主键字段
在Oracle、sqlserver中,不会被当做主键
*/
create table test_t_02 (my_int int unique not null)
desc test_t_02    # 可以看出my_int是PRI,被设置成了主键
​
# MySQL当中如果多个字段同时这也约束的话,因为一个表中只能允许一个主键,所以后面的my_int02字段会被定义为unique字段 且不能为空,但不是主键了
create table test_t_03 (my_int int unique not null,my_int02 int unique not null)
​

主键约束

特点

  • 主键约束相当于唯一约束+非空约束的组合,主键约束列不允许重复,也不允许出现空值

  • 一个表最多只能有一个主键约束,建立主键约束可以在列级别创建,也可以在表级别上创建

  • 主键约束对应着表中的一列或者多列(复合主键)

    • 如果是多列组合的复合主键约束,那么这些列都不允许为空值,并且组合的值不允许重复

# 声明主键时区别
# MySQL中的主键声明使用PRIMARY KEY关键字,Oracle、sqlserver中的主键声明使用CONSTRAINT关键字。
​
create table 表名称(
    字段名  数据类型  primary key, #列级约束
    字段名  数据类型
);
create table 表名称(
    字段名  数据类型,
    字段名  数据类型,  
    [constraint 约束名] primary key(字段名) #表级约束
);
​
​
​
CREATE TABLE `t_test_03` (
  `mysql_id` int(11) NOT NULL AUTO_INCREMENT,
  `mysql_varchar` varchar(30) DEFAULT '默认值',
  constraint mysql_t_test_03_pk PRIMARY KEY (`mysql_id`)
) 
​
​
#  复合主键
create table 表名称(
    字段名  数据类型,
    字段名  数据类型,  
    primary key(字段1,字段2...)  # 字段1、字段2、字段...的组合唯一
);

外键约束(foreign key)

外键约束:不能跨存储引擎使用

/*
父表:被引用的是父表
子表:引用的是子表
​
引用父表字段注意事项:
1、子表中的外键引用父表中的某个字段,被引用的这个字段不一定要求是主键,但至少具体unique约束的。如引用的外键重复了,那引用的到底是哪个,就不清楚;
2、外键可以为null
*/
#(从表的某个字段)的数据类型必须与主表名(被参考字段)的数据类型一致,逻辑意义也一样
#(从表的某个字段)的字段名可以与主表名(被参考字段)的字段名一样,也可以不一样
​
create table 从表名称(
    字段1  数据类型  primary key,
    字段2  数据类型,
    [CONSTRAINT 外键约束名称] FOREIGN KEY(子表字段) references 父表(字段)
);
​
create table t_class( # 父表
    class_no int primary key,
    classname varchar(255)
);
​
create table t_student( # 子表
    student_no int primary key auto_increment,
    name varchar(255),
    cno int comment '定义的外键,引用t_class表主键',
    
                    # FOREIGN KEY: 子表中的字段    REFERENCES: 父表中的字段
    CONSTRAINT t_student_fk foreign key(cno) references t_class(class_no)
)
​
insert into t_class values(3,'浙江省杭州实验小学一班')
insert into t_student values (3,'zhangsan',4)
​
​
当创建外键约束以后,做删除操作的时候要留意
​
比如要删除父表中的某条数据,但某个子表中又有对该条数据的引用,这时就会导致删除失败
​
删除时,可选方式
​
    -- 删除的时候,级联删除掉子表中的所有匹配行,在创建外键时,通过 on delete cascade子句指定外键可级联删除
​
    -- 删除父表中的对应行,会将对应子表中的所有匹配行的外键约束列置为NULL,通过on delete set null子句实施
​
    -- 默认,强制不让删除

检查约束(check)

检查约束:可以确保数据的完整性和一致性,限制满足特定条件的数据插入或更新 就是自定义的,如age这个字段的值定义了取值范围为1-100或某个字段的值定义了默认值

-- MySQL8版本以下不支持检查约束
-- sqlserver、oracle中支持
​
# 检查约束只对新插入的数据和更新的数据进行检查,不会对已存在的数据进行检查。如果需要对已存在的数据进行检查,可以使用ALTER TABLE语句来添加约束,并使用ENABLE VALIDATE选项来验证已存在的数据。
​
# oracle
CREATE TABLE T_T_01(
    ORA_INT NUMBER(8,0) CHECK(ORA_INT >1 AND ORA_INT <10),
    ORA_INT2 NUMBER(3,0) PRIMARY KEY, 
    CONSTRAINT T_T_01_pk PRIMARY KEY(ORA_INT2)
    -- 推荐都定义为表级约束
    -- CONSTRAINT check_value_range CHECK(ORA_INT >1 AND ORA_INT <10)
)
​
​
# sqlserver
create table sql_t_0001 (
    sql_int int, 
    sql_int_02 int ,
    constraint check_value_range check(sql_int_02 > 0),
    constraint sql_pk_01 primary key(sql_int)
    )
    
# mysql
create table new_t_01 (
    my_int int,
    my_int2 int,
    constraint mysql_pk primary key (my_int),
    constraint mysql_unique_value unique(my_int2)
)

数据库使用区别

分组

/*
在一条select语句当中,如果有group by语句的话,select后面只能跟参加分组的字段,以及聚合函数,其它的一律不能跟
*/
create table test_sex_01 (
    ID NUMBER(10,0),
    sex char(5),
    age NUMBER(3,0)
)
​
SELECT sex,max(ID) FROM test_sex_01 GROUP BY sex  
​
SELECT * FROM test_sex_01 GROUP BY sex # mysql可以跟其它的字段,虽然不会报错,但没啥意义

分页

数据库 关键字 公式
MySQL、Kingbase limit limit (pageNo-1) * pageSize , pageSize
Oracle rownum between...and...
SQL Server top 选择第m到n条记录 select top (n-m+1) * from table_name where a.id not in (select top m id from table_name)
DM limit、rownum都支持 limit (pageNo-1) * pageSize , pageSize
-- Oracle查询前5条
SELECT * FROM 
(SELECT * FROM AUTO_DATA_HOUSE_001 ORDER BY ORA_NUMBER_ID ) 
WHERE ROWNUM <= 5
​
​
/*
MySQL的分页查询使用的是偏移量(从0开始),而Oracle使用的是行数(从1开始)。此外,MySQL的LIMIT语句在处理大数据量时可能效率较低,而Oracle的分页查询在处理大数据量时可能更高效。
*/
​
select * from auto_api_table_100 limit 5
​
# sqlserver中查询前三条
select  top 3 * from sqlserver_to_oracle_01 
​
# sqlserver中查询后10条
select  top 10 * from sqlserver_to_oracle_01 order by SQL_ID desc 
​
# SQL Serever
​
# 达梦(支持limit和rownum)

字符串拼接

数据库 字符串拼接
MySQL、SQL Server concat()
Oracle、Kingbase、DM concat()或||且oracle中的concat只能有两个函数
-- Oracle、人大金仓、达梦中则可以使用concat()或者"||"进行拼接
SELECT CONCAT(TITLE,NATIONALNO)FROM "RESOURCES"."EMPLOYEE";
SELECT 'A' || 'B'||'C' FROM dual; 
select DM_CHAR || DM_CHARACTER || DM_VARCHAR from "SYSDBA"."dm_t_02"
​
-- SQL Server也支持字符"+"
​
select '字符串' + '拼接'

日期函数

数据库 time date datetime timestamp smalldatetime datetime2 datetimeoffset
MySQL curtime() curdate() now() sysdate() now() current_timestamp() 无此类型 无此类型 无此类型
SQL Serever SELECT CONVERT(char(10), getdate(), 108) SELECT CONVERT(char(10), getdate(), 120) getdate() sysdate() getdate() sysdatetime() getdate() sysdatetime() getdate() sysdatetime() SYSDATETIMEOFFSET()
Oracle 无此类型 SELECT sysdate FROM dual; 无此类型 同date语法一致 无此类型 无此类型 无此类型
DM current_time current_date current_timestamp current_timestamp 无此类型 无此类型 无此类型
Kingbase current_time current_date sysdate() current_timestamp 无此类型 无此类型 无此类型
-- MySQL示例
select current_time() as mysql_time ,current_date() as mysql_date,current_timestamp() as mysql_timestamp
​
# oracle的日期插入时,需要用到to_date()、to_timestamp()两个函数
# 达梦
    # 1.达梦插入日期时,分别用CURRENT_TIME、CURRENT_DATE、CURRENT_TIMESTAMP
    # 2.时间字符串转日期,to_date(),to_timestamp()
# SQL Server时间转字符串,convert()

主键自增关键字

主键自增只能指定整数类型,如decimal(10,0),numerice(10,0)均不能指定为自增

数据库 关键字 含义
MySQL、Kingbase auto_increment 默认每次递增1,可通过修改auto_increment_offset改变递增的步长以及初始值 show variables like 'auto_inc%'
SQL Server、DM IDENTITY(1,1) 第一个参数表示递增的起始值,第二个参数表示递增步长
Oracle12C IDENTITY(1,1)  

 

create table sql_test_t_01 (
    sql_int_1 int IDENTITY(1,1), 
    sql_int_2 int,
    sql_int_3 int,
    constraint sql_test_t_01_pk primary key(sql_int_1)
)
​
/*
在 Oracle 11g 中,需要先创建序列(SQUENCE)再创建一个触发器(TRIGGER)。
--oracle 使用序列自动增长:
    create sequence se_id 
    start with 1
    increment by 1
--使用序列实现自动增长:se_id.nextval
*/
​

覆盖插入

replace into和insert ignore into

场景:如果一条数据在表中已经存在,对其做update,如果不存在,将新的数据插入,如果不使用Oracle提供的merge语法的话,可能先要上数据库select查询一下看是否存在,然后决定怎么操作,这样的话需要来回数据库两次,同时性能也不好;

数据库 关键字 含义
MySQL replace into 根据主键或者唯一索引检查数据是否存在,如果存在就先删除在更新
  insert ignore into 忽略数据库中已经存在 的数据,如果数据库没有数据,就插入新的数据,如果有数据的话就跳过这条数据

 

-- replace into
replace into auto_api_table_1036 (id,mysql_tinyint,mysql_smallint,mysql_int,mysql_bigint,mysql_bit,mysql_float,mysql_decimal,mysql_double,mysql_char,mysql_varchar,mysql_tinytext,mysql_text,mysql_mediumint,mysql_date,mysql_time,mysql_datetime,mysql_year) VALUES
     (1,0,32767,101,100,1,777.99,888.77,555.55555,'随机插入积122','sfdsb','akfjba','mysql_text',7,'2022-07-15','17:23:26','2022-07-15 17:23:26',2022);
​
​
-- insert ignore into
​
insert ignore into auto_api_table_1036 (id,mysql_tinyint,mysql_smallint,mysql_int,mysql_bigint,mysql_bit,mysql_float,mysql_decimal,mysql_double,mysql_char,mysql_varchar,mysql_tinytext,mysql_text,mysql_mediumint,mysql_date,mysql_time,mysql_datetime,mysql_year) VALUES
     (1,0,32767,101,100,1,777.99,888.77,555.55555,'随机插入积122','sfdsb','akfjba','mysql_text',7,'2022-07-15','17:23:26','2022-07-15 17:23:26',2022);

merge into

数据库 关键字 含义
Oracle、SQL Server、DM MERGE INTO...USING.. 如果数据存在就更新,不存在就插入

 

/*语法格式:
MERGE INTO --要插入的表 别名
USING (
      --查询的SQL
      )别名 ON 
         --(连接条件)
WHEN MATCHED THEN -- 如果符合条件就更新(类似if)
     UPDATE SET 
WHEN NOT MATCHED THEN -- (类似else)
     INSERT ()VALUES();--不符合就插入 
*/
​
create table TEST_NIU_01 (ID number(20),NAME varchar2(20) ); 
​
insert into TEST_NIU_01 values (1, 'test1');  
insert into TEST_NIU_01 values (2, 'test2');
​
MERGE INTO TEST_NIU_01 A   -- 强调oracle不支持没有from的语句,sqlserver中可以直接select 1 as ID
USING (SELECT 1 as ID, 'newtest4' as NAME FROM DUAL) B on (A.ID=B.ID) 
WHEN MATCHED THEN   
UPDATE SET A.NAME=B.NAME  # where 1 = 0
WHEN NOT MATCHED THEN   
INSERT (A.ID, A.NAME) VALUES (B.ID, B.NAME ); 
​

人大金仓实现replace into

MySQL中也支持同样的语法

INSERT INTO t_pri_t_01 (king_int,king_char)VALUES (2,'alkhfd') ON DUPLICATE KEY UPDATE king_char='alkhfd';

查看表中索引

数据库 查看表索引
MySQL show index from 表名desc 表名
SQL Server exec sp_helpindex 表名
Oracle select * from user_ind_columns where table_name='表名'
DM Select * from dba_indexes where table_name = '表名'
Kingbase 请看下面人大金仓sql

查看表结构

数据库 查看表结构
MySQL show create table 表名;
SQL Server SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '表名'; EXEC sp_columns '表名';
Oracle SELECT DBMS_METADATA.GET_DDL('TABLE','表名') FROM DUAL;
DM SELECT DBMS_METADATA.GET_DDL('TABLE','表名称','模式名称') FROM dual; SELECT TABLEDEF('模式名','表名');
Kingbase 请看下面人大金仓sql
-- 人大金仓
select
    a.attnum,
    a.attname as field,
    a.attlen as length,
    a.atttypmod as lengthvar,
    a.attnotnull as notnull,
    b.description as comment
from
    sys_class c,
    sys_attribute a
left outer join sys_description b on
    a.attrelid = b.objoid
    and a.attnum = b.objsubid
where
    c.relname = '表名'
    and a.attnum > 0
    and a.attrelid = c.oid
order by
    a.attnum;

DDL

  • 新增字段

    -- MySQL新增字段
    alter table rename_t_01 add 字段名称 字段类型
    alter table rename_t_01 add column 字段名称 字段类型
    ​
    -- sqlserver
    alter table 表名 add 字段名称 字段类型
    ​
    -- Oracle
    alter table 表名 add 字段名称 字段类型

     

  • 修改表名/字段名称

    -- MySQL修改表名,to可省略
    alter table 原表名 rename [to] 新表名
    ​
    -- sqlserver修改表名[@newname可省略]
    EXEC sp_rename @objname = '原表名', @newname = '新表名'
    EXEC sp_rename '原表名','新表名'
    ​
    -- oracle修改表名
    alter table 原表名 rename to 新表名
    ​
    ​
    -- MySQL修改字段名称
    alter table 表名 change  原字段名称  新字段名称 字段类型
    alter table rename_t_01 change  old_field_char  new_field_char varchar(255)  # 也可修改字段类型
    ​
    -- sqlserver修改字段名称
    alter table 表名 rename column 原字段名称 to 新字段名称
    ​
    -- Oracle修改字段名称
    alter table 表名 rename column 原字段名称 to 新字段名称
  • 修改字段类型

    -- mysql [column]可省略
    alter table rename_t_01 modify [column] 字段名 字段类型
    ​
    -- sqlserver
    alter table 表名 alter column 字段名称 字段类型
    ​
    -- oracle
    alter table 表名 modify 字段名称 字段类型
  • 删除字段

    -- MySQL [column]可省略
    alter table 表名 drop 字段名称
    alter table 表名 drop column 字段名称
    ​
    -- SQL Server
    alter table 表名 drop column 字段名称
    ​
    -- Oracle
    ALTER TABLE 表名 DROP COLUMN 字段名称

建表时复制另外一个表的数据

-- mysql 
create table xxx as select * from 要复制的表  # as关键字可省略 慎用:只会拷贝表结构和数据,主键约束和其它约束都不会拷贝到的,字段的默认约束都不会拷贝
​
create table xxx  like 要复制的表  # 推荐使用这种,可以把表结构以及字段约束都拷贝过来
​
-- sqlserver
select * into xxx from 要复制的表
​
-- oracle、 达梦、人大金仓
create table xxx as select * from 要复制的表
​
​
-- 以上除了mysql的create ... like ... 能把约束拷贝过来,其它不支持;

DML

-- MySQL、SQL Server
insert into 表名 (field01,field02,field..) values(value01,value02,value...)
# MySQL中可以一次插入多条
insert into 表名 (field01,field02,field..) values(value01,value02,value...),(value01,value02,value...),(value01,value02,value...)
​
-- SQL Server、Oracle中批量插入(注意分号不可省略!!!)
begin
    INSERT INTO T_ORACLE_01_COPY_AS_NEW (ID,NUMEBER18,ORACLE_CHAR) VALUES (2,2,'2');
    INSERT INTO T_ORACLE_01_COPY_AS_NEW (ID,NUMEBER18,ORACLE_CHAR) VALUES (3,3,'3');
    INSERT INTO T_ORACLE_01_COPY_AS_NEW (ID,NUMEBER18,ORACLE_CHAR) VALUES (4,4,'4');
end;

复制插入

-- mysql
insert into temp_t_sql_01  as select * from t_services_table_01  # as 关键字可省略
​
-- sqlserver,表中不能含有timestamp类型
insert into temp_t_sql_01  select * from t_services_table_01  # 不可使用 as 关键字
​
-- oracle,表中不能含有long类型
INSERT INTO T_ORACLE_01_COPY SELECT ID,NUMEBER18, ORACLE_CHAR FROM T_ORACLE_01  # 不可使用 as 关键字
​
-- 达梦、人大金仓
insert into xxx select * from  bbb  # 不可使用 as 关键字

导入sql文件

数据库 关键字 使用方式
MySQL、Oracle source 命令行
sqlserver :r 命令行
达梦 dexp 命令行

MySQL

source

source命令需要在mysql命令行中才可使用

# 1.先把要导入的sql文件拷贝到容器里面,说明:如果容器开启数据卷挂载的话,不需要此步骤
docker cp create01.sql fac859d9d515:/home
# 2.进入mysql容器,连接mysql
mysql -uroot -p123456
# 3.切换到要导入的数据库
use 要切换的库
# 4.source sql文件路径
source /home/create01.sql

导入多个sql文件

场景:排查现场问题时,现场给了很多个sql文件

  • 步骤1(先把sql文件依次上传到容器)

image-20230620155327685

  • 步骤2:新建一个文件,把每个sql文件所在路径写入到此文件

image-20230620155448124

  • 步骤3:连接数据库并切换到对应的数据库,执行导入

    image-20230620160138458

     

SQL Server

sqlcmd

# 步骤1.先把要导入的sql文件拷贝到容器里面,说明:如果容器开启数据卷挂载的话,不需要此步骤
​
# 步骤2:进入sqlserver所在容器,找到sqlcmd所在目录,登录sqlserver
./sqlcmd -U 用户名 -P 密码
​
# 步骤3:切换到要到导入的数据库
1> use auto_database
2> go   # sqlserver要以GO去触发sql的执行,大小写皆可
Changed database context to 'auto_database'.
1> :r /home/sqlserver01.sql
2> go

导入多个sql文件

  • 步骤1(先把sql文件依次上传到容器)

image-20230620192328704

  • 步骤2:新建一个文件,把每个sql文件所在路径写入到此文件

image-20230620192415294

  • 步骤3:连接数据库并切换到对应的数据库,执行导入

image-20230620192504756

Oracle

# 1.先把要导入的sql文件拷贝到容器里面,说明:如果容器开启数据卷挂载的话,不需要此步骤
# 2.进入Oracle容器,连接Oracle
sqlplus /nolog
connect sys as sysdba;
根据提示输入对应的密码:
# 3.source sql文件路径
@ /home/create01.sql

导入多个文件

步骤同mysql、sqlserver。文件内容写入:@ /sql文件所在路径

DQL

查询都有哪些数据库

-- MySQL
show databases;
​
-- SQL Server
SELECT name FROM sys.databases;
​
-- Oracle
SELECT * FROM ALL_USERS;

统计表中有多少列

表名不存在,则返回0

-- Oracle
SELECT COUNT(*) AS column_count FROM all_tab_columns WHERE table_name = '表名';  # 表名要大写;
​
-- MySQL/SQL Server
select count(*) as column_count  from information_schema.columns where table_name = '表名';
​
-- SQL Server
SELECT COUNT(*) AS column_count FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '表名';  
​
-- 达梦
select * from all_tab_columns where owner='模式名' and Table_Name='表名'

查看当前所在的库

场景:DBeaver开的窗口较多时,容易混淆当前所在的Schema

数据库 Schema
MySQL select databse()
SQL Server SELECT DB_NAME() AS CurrentDatabase;
Oracle、DM、Kingbase SELECT USER AS CurrentSchema FROM DUAL;

查看连接数

-- oracle 查看最大连接数
SELECT NAME, VALUE FROM V$PARAMETER WHERE NAME = 'processes';
​
-- sqlserver查看当前连接数
SELECT COUNT(*) AS connection_count FROM V$SESSION;
​
-- mysql
show variables like '%connect%'   -- max_connections
​
-- 达梦
select clnt_ip,user_name,state,count(*) from v$sessions group by clnt_ip,user_name,state;

创建视图以及复制

创建视图

小提示:统一跟上as关键字方便记忆

-- Oracle、SQL Serever、达梦 as关键字不可省略
CREATE VIEW  RECEIVE_HANA_01_view  AS SELECT * FROM RECEIVE_HANA_01  # as关键字不可省略
​
-- mysql 的as关键字可省略

创建表,并把表数据也同步过去

-- MySQL
create table xxx as select * from bbb;  # as关键字可省略
​
-- Oracle 复制的表不能含有long类型
-- CREATE TABL T_ORACLE_01_COPY AS select column1,column2... from table_name_old;
CREATE TABLE T_ORACLE_01_COPY  AS SELECT ID,NUMEBER18, ORACLE_CHAR FROM T_ORACLE_01  # as关键字不可省略
​
-- sqlserver 不支持这样创建
​

复制表结构

-- mysql 
create table xxx as select * from 要复制的表  # as关键字可省略 慎用:只会拷贝表结构和数据,主键约束和其它约束都不会拷贝到的,字段的默认约束都不会拷贝
​
create table xxx  like 要复制的表  # 推荐使用这种,可以把表结构以及字段约束都拷贝过来(仅在MySQL当中支持此种语法)

 

存储引擎

存储引擎可以分为两部分理解,一部分是存储,一部分是引擎 存储:是把数据存储到磁盘上

引擎:是为数据存储到磁盘上增加动力的,即:提升数据存储的速度同时也对数据更新提升速度优化I/O

mysql

/*
MYISALM:速度优先,索引也支持 B+tree、锁是表锁
​
•   `.frm文件`:存储表结构
​
•   `.myd文件`:存储表数据
​
•   `.myi文件`:存储索引
​
同等数据量的数据,从磁盘上获取数据,MyISAM存储引擎速度要快一些
​
INNODB:事务优先、索引是B+tree、锁是行锁
​
•   `.frm文件`:存储表结构
​
•   `.bd文件`:存储表数据和索引
*/
root@fac859d9d515:/var/lib/mysql/auto_database# ls |grep -e t_test_01
t_test_01.frm
t_test_01.ibd
root@fac859d9d515:/var/lib/mysql/auto_database# ls |grep -e t_test_02
t_test_02.MYD
t_test_02.MYI
t_test_02.frm
​

sqlserver

/*
.mdf:数据主文件
.ndf:辅助文件也可以存储数据
ndf可以有多个但是mdf只能有一个
.ldf:日志文件
*/
root@3b764e638b67:/var/opt/mssql/data# ls
bd_modle.mdf           cdc_auto_database_log.ldf       cdc_test.mdf      mastlog.ldf   msdbdata.mdf        receive_oracle_log.ldf             sql_auto_database.mdf      templog.ldf
bd_modle_log.ldf       cdc_jdbc_auto_database.mdf      cdc_test_log.ldf  model.mdf     msdblog.ldf         receive_sql_auto_database.mdf      sql_auto_database_log.ldf
cdc_auto_database.mdf  cdc_jdbc_auto_database_log.ldf  master.mdf        modellog.ldf  receive_oracle.mdf  receive_sql_auto_database_log.ldf  tempdb.mdf

oracle

表空间(.bdf):由数据文件组成.用户的各种模式对象(如表, 索引, 过程, 触发器等) 都是放在表空间中

每个用户都可以指定独立的表空间,若不给用户指定默认的表空间,则用户的默认表空间为USERS表空间

数据文件:物理存储单位,

一个表空间可以由一个或多个和数据文件组成,数据库的数据是存储在表空间中的

Oracle 数据库是数据的物理存储。这就包括(数据文件 ORA 或者 DBF、控制文件、联机日志、参数文件)

CDC(Change Data Capture)

变化数据捕获简称CDC,记录了所有的DDL和DML语句

MySQL

MYSQL 通过开启 binlog 日志,提供 CDC 数据同步能力。CDC 配置工作包含两个操作:

(1)数据库实例开启 binlog 日志,

(2)同步账户授予 CDC 操作权限。

说明:

操作(1)针对的是整个数据库实例,只需操作一次即可,操作完后需要重启数据库才能使配置生效。

操作(2)以同步账户为单位进行配置,在此建议针对每个 MYSQL 实例创建全局统一的同步账户,这样也只需配置一次即可。

/*
步骤说明:若满足1、2步骤则直接执行步骤5,否则依次执行
*/
​
-- 1.检查bin-log是否开启,以管理员账户root登录数据库 
mysql -u用户名 -p密码
show variables like 'log_bin'; -- 未开启:OFF   已开启:ON
​
-- 2.检查相关参数的配置是否符合要求
show variables like '%binlog_format%';   -- 值应为“ROW”
show variables like '%binlog_row_image%'; -- 值应为:“FULL”
​
-- 3.配置文件增加bin-log开启配置
/*
log-bin=binlog
log-bin-index=binlog.index
binlog_format=row
server_id=1
binlog_row_image = full
gtid_mode = on
enforce_gtid_consistency = on
expire_logs_days = 10
​
server-id 的值应为大于 1 的整数,请根据实际规划设置,并且在创建数据集成任务时设置的“Server Id”值需要此处设置的值不同。
expire_logs_days 为 Binlog 日志文件保留时间,超过保留时间的 Binlog 日志会被自动删除,应保留至少2天的日志文件。
“gtid_mode = on”和“enforce_gtid_consistency = on”仅当 MySQL 的版本大于等于5.6.5 时才需要添加,否则删除这两行内容。
*/
​
-- 4.保存配置文件,重启数据库;使配置生效
​
-- 5.创建账户,并授权
CREATE USER '用户名'@'%' IDENTIFIED BY '密码';
GRANT SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO '用户名'@'%';

SQL Server

-- 1.查询数据库是否开启cdc
select is_cdc_enabled from sys.databases where name='supdam'   -- 0:未开启   1:已开启
​
-- 2.开启数据库cdc(切换到对应的数据库下,如:use test_db)
exec sys.sp_cdc_enable_db
​
-- 3.开启数据表cdc
EXEC sys.sp_cdc_enable_table
@source_schema = 'dbo', -- 表所在数据库 scheme
@source_name = '数据表名',
@supports_net_changes = 1, 
@role_name = NULL  -- 访问控制角色名

Oracle

Oracle开启CDC参考文档