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 肯定可能为空
oracle可以,db2不可以
本回答被提问者采纳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不让创建的主要内容,如果未能解决你的问题,请参考以下文章
在Oracle数据库中创建一个表,用两个键做联合主键,sql语句该怎么写?