我有一个表,我需要两个值都是主要的,因为我在其他表中将此组合作为外键引用。表定义和我需要输入的数据如下
create table T1
(
sno number(10),
desc varchar2(10),
constraint T1_PK primary key(sno,desc)
)
DATA to put
sno | desc
---------------------------
100 | "hundred"
000 | null
120 | "one twenty"
123 | "" <EMPTY STRING>
000 | "" <EMPTY STRING>
这里的问题是desc有时可能为null。主键不能为null所以当我遇到空值时 - 我只是在表中插入“”。这里的问题是有时候desc可能有空字符串。 如果我插入约数据100,Null和100,“”是两个不同的东西,但我无法将它们放在表中。如果为null,我不想放置像'EMPTY'这样的字符串,因为它可能会使正在查看该表的最终用户感到困惑。
1)如何将desc作为主键处理null的情况。我无法使用自动序列号。 2)如何区分由我引入的空字符串和已经存在的空字符串?
答案 0 :(得分:8)
为什么不引入自动递增的真实主键属性(如id)并在sno和desc上创建索引?
答案 1 :(得分:6)
Oracle将空VARCHAR
字段视为NULL
的同义词,这有点争议,但这是您必须要忍受的。因此,您无法将空字符串放入主键,因为您无法将NULL
放入主键中。
我的建议?使用一个数字的技术主键(在MySQL / SQL Server中自动递增,来自Oracle中的SEQUENCE
)。在其他字段对上放置一个唯一索引。所以:
CREATE TABLE t1 (
id NUMBER(10) PRIMARY KEY,
sno NUMBER(10),
desc VARCHAR2(10)
);
CREATE SEQUENCE t1_seq;
答案 2 :(得分:4)
desc永远不应该在主键中。它根本不需要它。在关系数据库理论中,阅读一个主要关键点。
那就是说,你想要的是不可能的 - 根据关系理论,主键不允许使用“未定义”值,因为它们必须是唯一的 - 这是SQL部署的三元逻辑的一部分。
有人真的在你的数据库设计上做得不好。射击不好。
答案 3 :(得分:0)
使用CHAR而不是VARCHAR。空将为空。需要设置一个空格而不是空字符串,以避免Oracle将空字符串转换为NULL。请注意,在CHAR字段上,空格与两个空格,三个空格相同......(但它与Oracle的零空格不同)。