db2中创建联合主键,发现一个字段可以为null,但是db2不让创建

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了db2中创建联合主键,发现一个字段可以为null,但是db2不让创建相关的知识,希望对你有一定的参考价值。

这个是oracle中的脚本,其 BE_ID 字段没定义为:not null,但是没影响下面联合主键的创建。但是……

create table MM_PUB_RULEATOM_LEVELRELATE
(
LEVELID VARCHAR2(50) not null,
ATOMID VARCHAR2(64) not null,
STATUS VARCHAR2(10),
SOURCETYPE VARCHAR2(20),
FK VARCHAR2(32),
HANDLER VARCHAR2(32),
HIDEONCLICK VARCHAR2(10),
SEQNUM VARCHAR2(20),
BE_ID NUMBER(10)
)
;
alter table MM_PUB_RULEATOM_LEVELRELATE
add constraint PK_PUB_RULEATOM_LEVELRELATE primary key (LEVELID, ATOMID,BE_ID);

问题来了——现在将oracle脚本该为db2脚本执行时(项目中不再使用oracle,而是使用db2),对应的db2脚本如下:
create table MM_PUB_RULEATOM_LEVELRELATE
(
LEVELID VARCHAR(50) not null,
ATOMID VARCHAR(64) not null,
STATUS VARCHAR(10),
SOURCETYPE VARCHAR(20),
FK VARCHAR(32),
HANDLER VARCHAR(32),
HIDEONCLICK VARCHAR(10),
SEQNUM VARCHAR(20),
BE_ID DECIMAL(10)
)
;
alter table MM_PUB_RULEATOM_LEVELRELATE
add constraint PK_PUB_RULEATOM_LEVELRELATE primary key (LEVELID, ATOMID,BE_ID);
执行发现:
Error 2013/11/1 10:53:15 0:00:00.000 DB2 Database Error: ERROR [42831] [IBM][DB2/LINUXX8664] SQL0542N The column named "BE_ID" cannot be a column of a primary key or unique key constraint because it can contain null values. SQLSTATE=42831
即,BE_ID不能为空在db2中创建联合主键时,求oracle或者db2专家们给点指导,如何处理?因为业务中 BE_ID 肯定可能为空

参考技术A 主键是不允许出现null值,追问

oracle可以,db2不可以

本回答被提问者采纳

MySQL-DAY03

MySQL-DAY03

1.约束

在创建表的时候,可以给表的字段添加相应的约束,添加约束的目的是为了保证表中数据的合法性、有效性、完整性。

常见约束:

  • 非空约束(not null):约束的字段不能为NULL

  • 唯一约束(unique):约束的字段不能重复

  • 主键约束(primary key):约束的字段既不能为NULL,也不能重复(简称PK)

    • 每个表应该具有主键,主键可以标识记录的唯一性,主键分为单一主键和复合(联合)主键,单一主键是由一个字段构成的,复合(联合)主键是由多个字段构成的。

  • 外键约束(foreign key):...(简称FK)

  • 检查约束(check):注意Oracle数据库有check约束,但是mysql没有,目前mysql不支持该约束。

1.1主键约束

  • 主键相关的术语?

    • 主键约束 : primary key

    • 主键字段 : id字段添加primary key之后,id叫做主键字段

    • 主键值 : id字段中的每一个值都是主键值。

  • 主键有什么作用?

    • 表的设计三范式中有要求,第一范式就要求任何一张表都应该有主键。

    • 主键的作用:主键值是这行记录在这张表当中的唯一标识。(就像一个人的身份证号码一样。)

  • 主键的分类?

    • 根据主键字段的字段数量来划分:

      • 单一主键(推荐的,常用的。)

      • 复合主键(多个字段联合起来添加一个主键约束)(复合主键不建议使用,因为复合主键违背三范式。)

  • 根据主键性质来划分:

    • 自然主键:主键值最好就是一个和业务没有任何关系的自然数。(这种方式是推荐的)

    • 业务主键:主键值和系统的业务挂钩,例如:拿着银行卡的卡号做主键,拿着身份证号码作为主键。(不推荐用)

      • 最好不要拿着和业务挂钩的字段作为主键。因为以后的业务一旦发生改变的时候,主键值可能也需要随着发生变化,但有的时候没有办法变化,因为变化可能会导致主键值重复。

  • 一张表的主键约束只能有1个。(必须记住)

    create table t_user(
id int primary key, // 列级约束
username varchar(255),
email varchar(255)
);
create table t_user(
id int,
username varchar(255),
primary key(id) //表级约束
);
  • mysql提供主键值自增:(非常重要。)

    drop table if exists t_user; create table t_user( id int primary key auto_increment, // id字段自动维护一个自增的数字,从1开始,以1递增。 username varchar(255) ); insert into t_user(username) values(‘a‘); insert into t_user(username) values(‘b‘); insert into t_user(username) values(‘c‘); insert into t_user(username) values(‘d‘); insert into t_user(username) values(‘e‘); insert into t_user(username) values(‘f‘); select * from t_user;

1.2 外键约束

  • 关于外键约束的相关术语:

    • 外键约束: foreign key

    • 外键字段:添加有外键约束的字段

    • 外键值:外键字段中的每一个值。

  • 将以上表的建表语句写出来:

    t_student中的classno字段引用t_class表中的cno字段,此时t_student表叫做子表。t_class表叫做父表。

    • 顺序要求:

      • 删除数据的时候,先删除子表,再删除父表。

      • 添加数据的时候,先添加父表,在添加子表。

      • 创建表的时候,先创建父表,再创建子表。

      • 删除表的时候,先删除子表,在删除父表。

  • 外键值可以为NULL。

  • 外键字段引用其他表的某个字段的时候,被引用的字段不一定是主键,但至少具有unique约束。

2. 存储引擎(了解)

  • 数据库中的各表均被(在创建表时)指定的存储引擎来处理。

  • 服务器可用的引擎依赖于以下因素:

    • MySQL的版本

    • 服务器在开发时如何被配置

    • 启动选项

  • 为了解当前服务器中有哪些存储引擎可用,可使用SHOW ENGINES语句:

    mysql> SHOW ENGINESG
  • 在创建表时,可使用ENGINE选项为CREATE TABLE语句显式指定存储引擎。

    CREATE TABLE TABLENAME (NO INT) ENGINE = MyISAM;
  • 如果在创建表时没有显式指定存储引擎,则该表使用当前默认的存储引擎

  • 默认的存储引擎可在my.ini配置文件中使用default-storage-engine选项指定。

  • 现有表的存储引擎可使用ALTER TABLE语句来改变:

    ALTER TABLE TABLENAME ENGINE = INNODB;
  • 为确定某表所使用的存储引擎,可以使用SHOW CREATE TABLE或SHOW TABLE STATUS语句:

    mysql> SHOW CREATE TABLE empG
?
mysql> SHOW TABLE STATUS LIKE ‘emp‘ G

3. 事务

3.1 概述

一个事务是一个完整的业务逻辑单元,不可再分。

事务可以保证多个操作原子性,要么全成功,要么全失败。

对于数据库来说事务保证批量的DML(insert delete update)要么全成功,要么全失败。

3.2 事物的特性

事务具有四个特征:ACID

  • a) 原子性(Atomicity)

    整个事务中的所有操作,必须作为一个单元全部完成(或全部取消)。

    事务是最小的工作单元,不可再分。

  • b) 一致性(Consistency)

    在事务开始之前与结束之后,数据库都保持一致状态。

    事务必须保证多条DML语句同时成功或者同时失败。

  • c) 隔离性(Isolation)

    一个事务不会影响其他事务的运行。

  • d) 持久性(Durability)

    在事务完成以后,该事务对数据库所作的更改将持久地保存在数据库之中,并不会被回滚。

    最终数据必须持久化到硬盘文件中,事务才算成功的结束。

3.3 事务中存在一些概念:

a) 事务(Transaction):一批操作(一组DML)

b) 开启事务(Start Transaction)

c) 回滚事务(rollback)

d) 提交事务(commit)

e) SET AUTOCOMMIT:禁用或启用事务的自动提交模式

当执行DML语句是其实就是开启一个事务。

关于事务的回滚需要注意:只能回滚insert、delete和update语句,不能回滚select(回滚select没有任何意义),对于create、drop、alter这些无法回滚.

事务只对DML有效果。

注意:rollback,或者commit后事务就结束了。

3.4 事务的隔离性

3.4.1 隔离级别

事务隔离性存在隔离级别,理论上隔离级别包括4个:

  • 第一级别:读未提交(read uncommitted)

    • 对方事务还没有提交,我们当前事务可以读取到对方未提交的数据。

    • 读未提交存在脏读(Dirty Read)现象:表示读到了脏的数据。

  • 第二级别:读已提交(read committed)

    • 对方事务提交之后的数据我方可以读取到。

    • 这种隔离级别解决了: 脏读现象没有了。

    • 读已提交存在的问题是:不可重复读

  • 第三级别:可重复读(repeatable read)

    • 这种隔离级别解决了:不可重复读问题。

    • 这种隔离级别存在的问题是:读取到的数据是幻象

    • 该隔离级别为InnoDB的缺省设置。

  • 第四级别:序列化读/串行化读(serializable)

    • 解决了所有问题。

    • 效率低,需要事务排队。

oracle数据库默认的隔离级别是:读已提交。

mysql数据库默认的隔离级别是:可重复读。

技术图片

3.4.2 作用范围

事务隔离级别的作用范围分为两种:

  • 全局级:对所有的会话有效

  • 会话级:只对当前的会话有效

例如,设置会话级隔离级别为READ COMMITTED :

mysql> SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

设置全局级隔离级别为READ COMMITTED :

演示第1级别:读未提交
set global transaction isolation level read uncommitted;
演示第2级别:读已提交
set global transaction isolation level read committed;
演示第3级别:可重复读
set global transaction isolation level repeatable read;

3.4.3 查看隔离级别

  • 服务器变量tx_isolation(包括会话级和全局级两个变量)中保存着当前的会话隔离级别。

  • 为了查看当前隔离级别,可访问tx_isolation变量:

查看会话级的当前隔离级别:

mysql> SELECT @@tx_isolation;
或:
mysql> SELECT @@session.tx_isolation;

查看全局级的当前隔离级别:

mysql> SELECT @@global.tx_isolation;

3.5 自动提交模式

  • 自动提交模式用于决定新事务如何及何时启动。

  • 启用自动提交模式:

    • 如果自动提交模式被启用,则单条DML语句将缺省地开始一个新的事务。

    • 如果该语句执行成功,事务将自动提交,并永久地保存该语句的执行结果。

    • 如果语句执行失败,事务将自动回滚,并取消该语句的结果。

    • 在自动提交模式下,仍可使用START TRANSACTION语句来显式地启动事务。这时,一个事务仍可包含多条语句,直到这些语句被统一提交或回滚。

  • 禁用自动提交模式:

    • 如果禁用自动提交,事务可以跨越多条语句。

    • 在这种情况下,事务可以用COMMIT和ROLLBACK语句来显式地提交或回滚。

  • 自动提交模式可以通过服务器变量AUTOCOMMIT来控制。

mysql> SET AUTOCOMMIT = OFF; 
?
mysql> SET AUTOCOMMIT = ON;
?

?
mysql> SET SESSION AUTOCOMMIT = OFF;
?
mysql> SET SESSION AUTOCOMMIT = ON;
?
show variables like ‘%auto%‘; -- 查看变量状态

4 索引

4.1 原理

索引被用来快速找出在一个列上用一特定值的行。

没有索引,MySQL不得不首先以第一条记录开始,然后读完整个表直到它找出相关的行。表越大,花费时间越多。

对于一个有序字段,可以运用二分查找(Binary Search),这就是为什么性能能得到本质上的提高。MYISAM和INNODB都是用B+Tree作为索引结构。

通过B+Tree缩小扫描范围,底层索引进行了排序,分区,索引会携带数据在表中的“物理地址”,最终通过索引检索到数据之后,获取到关联的物理地址,通过物理地址定位表中的数据,效率是最高的。

select ename from emp where ename = ‘SMITH‘;
通过索引转换为:
select ename from emp where 物理地址 = 0x3;
  • 主键,unique 都会默认的添加索引。

  • 根据主键查询效率较高。尽量根据主键检索。

4.2 索引的分类

  • 单一索引:给单个字段添加索引

  • 复合索引:给多个字段联合起来添加1个索引

  • 主键索引:主键上会自动添加索引

  • 唯一索引:有unique约束的字段上会自动添加索引

4.3 创建索引

什么时候需要给字段添加索引:

  • 表中该字段中的数据量庞大

  • 经常被检索,经常出现在where子句中的字段

  • 经常被DML操作的字段不建议添加索引

索引等同于一本书的目录。

主键会自动添加索引,所以尽量根据主键查询效率较高。

create unique index 索引名 on 表名(列名); 
alter table 表名 add unique index 索引名 (列名);

4.4 查看、使用、删除索引

show index from 表名;
explain select 列名 from 表名 where 条件;
drop index 索引名称 on 表名;

5 视图

5.1 概述

  • 视图是一种根据查询(也就是SELECT表达式)定义的数据库对象,用于获取想要看到和使用的局部数据。

  • 视图有时也被成为“虚拟表”。

  • 视图可以被用来从常规表(称为“基表”)或其他视图中查询数据。

  • 相对于从基表中直接获取数据,视图有以下好处:

    • 访问数据变得简单

    • 可被用来对不同用户显示不同的表的内容

    • 用来协助适配表的结构以适应前端现有的应用程序

视图作用:

  • 提高检索效率

  • 隐藏表的实现细节【面向视图检索】

技术图片

5.2 创建、修改、删除视图?

create view myview as select empno,ename from emp;
alter view v_dept_emp as select ename,e.deptno from emp e,dept d where e.deptno = 20;
drop view myview;

注意:只有DQL语句才能以视图对象的方式创建出来。

对视图进行增删改查,会影响到原表数据。(通过视图影响原表数据的,不是直接操作的原表)

可以对视图进行CRUD操作。

6 DBA命令

6.1 将数据库当中的数据导出

在windows的dos命令窗口中执行:(导出整个库)

mysqldump bjpowernode>D:jpowernode.sql -uroot -p333

在windows的dos命令窗口中执行:(导出指定数据库当中的指定表)

mysqldump bjpowernode emp>D:jpowernode.sql -uroot –p123

6.2 导入数据

create database bjpowernode;
use bjpowernode;
source D:jpowernode.sql

7 数据库设计三范式

设计范式是设计表的依据。按照这个三范式设计的表不会出现数据冗余。

三范式:

  • 第一范式:任何一张表都应该有主键,并且每一个字段原子性不可再分。

  • 第二范式:建立在第一范式的基础之上,所有非主键字段完全依赖主键,不能产生部分依赖。

    • 多对多?三张表,关系表两个外键。

  • 第三范式:建立在第二范式的基础之上,所有非主键字段直接依赖主键,不能产生传递依赖。

    • 一对多?两张表,多的表加外键。

一对一设计有两种方案:主键共享、外键唯一。



以上是关于db2中创建联合主键,发现一个字段可以为null,但是db2不让创建的主要内容,如果未能解决你的问题,请参考以下文章

sql中创建组合主键和组合外键

在Oracle数据库中创建一个表,用两个键做联合主键,sql语句该怎么写?

如何在 Django 中创建一个包含两个字段的主键?

MySQL - InnoDB主键索引、普通索引、唯一索引、联合索引

是否可以命名在 oracle 中创建主键期间创建的索引?

mysql表中一个表中可以有多个主键吗