Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何使用可选的FK创建索引? 原始问题_Sql_Relational Database_Hsqldb - Fatal编程技术网

Sql 如何使用可选的FK创建索引? 原始问题

Sql 如何使用可选的FK创建索引? 原始问题,sql,relational-database,hsqldb,Sql,Relational Database,Hsqldb,因此,我没有创建的业务模型具有可选关系(如ER模型)。我已经有一段时间没有在DB工作了,所以我可能忘记了什么。当前第一个表的FK(外键)指向第二个表的PK(主键),是一个ID;我不记得这个词了,但它是“假的”,而不是RDBMS(关系数据库管理系统)使用的“真的”。为了简单起见,让我们假设只有两个表 当前,当不需要可选关系时,FK列/属性中有空值。当该列中有一个项目时,我希望获得全部优势,检查FK指向(第二个表)的关系的另一端是否有匹配的项目,也会触发(尽管当前没有)和其他验证。直到不久前,当我意

因此,我没有创建的业务模型具有可选关系(如ER模型)。我已经有一段时间没有在DB工作了,所以我可能忘记了什么。当前第一个表的FK(外键)指向第二个表的PK(主键),是一个ID;我不记得这个词了,但它是“假的”,而不是RDBMS(关系数据库管理系统)使用的“真的”。为了简单起见,让我们假设只有两个表

当前,当不需要可选关系时,FK列/属性中有空值。当该列中有一个项目时,我希望获得全部优势,检查FK指向(第二个表)的关系的另一端是否有匹配的项目,也会触发(尽管当前没有)和其他验证。直到不久前,当我意识到我不想在第一个表的重要部分重复时,我还是很满意的,所以我想创建一个唯一的键,但似乎无法创建一个键,其中包含一个可能包含null的列/属性。到目前为止,有两种解决方案向我提出,尽管我都不了解

第一个是我设置了默认值,0表示基于数字的类型,空字符串(“”)表示基于字符的类型。我没有得到的是,第二个表已经有了一个具有相应值(0)的行/元组。如果我要将当前行移动到没有默认行的位置,那么我假设我会在相应的内容中也添加一个默认行,在我的例子中,它是基于字符的类型。因此,启用索引的“成本”是通过软件进行大量无用的连接,然后进行大量无用的合并,在我的例子中是office套件的数据库部分,ApacheOpenOffice Base。这看起来像是增加了很多处理,在我看来某种触发器,加上我目前的设计,会更好

第二个是制作一个“链接”表(他/她的术语),一个多对多的关系,但我认为这些仅适用于具有1个以上可能关系的条目;拥有0-1关系将不会使用它。无论如何,我仍然会遇到同样的问题,在“链接”表中不需要有条目。IIRC,该表的2个“边”必须包含有效的候选键

因此,对于业务模型确实需要该选项的情况,已经实现了1-1关系,FK中的当前项为非空。现在,我只需要为业务模型不需要可选部分的情况实现一个方法,以允许FK中当前空条目的0-1关系,同时不允许重复

谢谢你的帮助

要求 现在包含第三个示例

下面的小节包含使用命令
脚本'PATH\TO\NAME.SQL'
从Apache OpenOffice Base导出的半SQL。原始文件及其导出和未导出的查询处于打开状态

我想在3列/属性ID_to_part1、型号编号&ID_to_part2上有一个唯一的键;但是,上一节中的原始问题show HSQLDB version 1.8.0.10不允许在作为唯一键的一部分的列中包含null

HSQLDB导出 生成某种SQL;包括非标准声明

SET DATABASE COLLATION "Latin1_General"
CREATE SCHEMA PUBLIC AUTHORIZATION DBA
CREATE CACHED TABLE "Table1"("ID" INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,"ID_to_part1" INTEGER NOT NULL,"model_number" VARCHAR_IGNORECASE(3) NOT NULL,"ID_to_part2" INTEGER)
CREATE CACHED TABLE "Table2"("ID" INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,"content" VARCHAR_IGNORECASE(1) NOT NULL)
CREATE CACHED TABLE "Table3"("ID" INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL PRIMARY KEY,"content" VARCHAR_IGNORECASE(1) NOT NULL)
ALTER TABLE "Table1" ADD CONSTRAINT SYS_FK_87 FOREIGN KEY("ID_to_part1") REFERENCES "Table3"("ID") ON DELETE CASCADE ON UPDATE CASCADE
ALTER TABLE "Table1" ADD CONSTRAINT SYS_FK_90 FOREIGN KEY("ID_to_part2") REFERENCES "Table2"("ID") ON DELETE SET NULL ON UPDATE CASCADE
ALTER TABLE "Table1" ALTER COLUMN "ID" RESTART WITH 15
ALTER TABLE "Table2" ALTER COLUMN "ID" RESTART WITH 2
ALTER TABLE "Table3" ALTER COLUMN "ID" RESTART WITH 4
CREATE USER SA PASSWORD ""
GRANT DBA TO SA
SET WRITE_DELAY 0 MILLIS
SET SCHEMA PUBLIC
INSERT INTO "Table1" VALUES(0,0,'123',0)
INSERT INTO "Table1" VALUES(1,1,'456',NULL)
INSERT INTO "Table1" VALUES(2,2,'789',0)
INSERT INTO "Table1" VALUES(3,0,'012',1)
INSERT INTO "Table1" VALUES(6,3,'345',NULL)
INSERT INTO "Table1" VALUES(7,1,'678',1)
INSERT INTO "Table1" VALUES(8,0,'123',NULL)
INSERT INTO "Table1" VALUES(9,0,'123',1)
INSERT INTO "Table1" VALUES(10,1,'456',0)
INSERT INTO "Table1" VALUES(11,1,'456',1)
INSERT INTO "Table1" VALUES(12,1,'456',0)
INSERT INTO "Table1" VALUES(13,1,'123',NULL)
INSERT INTO "Table1" VALUES(14,1,'123',0)
INSERT INTO "Table2" VALUES(0,'B')
INSERT INTO "Table2" VALUES(1,'E')
INSERT INTO "Table3" VALUES(0,'A')
INSERT INTO "Table3" VALUES(1,'C')
INSERT INTO "Table3" VALUES(2,'D')
INSERT INTO "Table3" VALUES(3,'F')
似乎没有导出查询,这里是查询结果

问题1 已联接的主表:

SELECT "Table1"."ID", "Table3"."content" AS "Table3_content", "Table1"."model_number", "Table2"."content" AS "Table2_content"
    FROM "Table1"
        LEFT OUTER JOIN "Table2" ON "Table1"."ID_to_part2" = "Table2"."ID"
        LEFT OUTER JOIN "Table3" ON "Table1"."ID_to_part1" = "Table3"."ID"
    ORDER BY "ID" ASC
结果:

ID    Table3_content    model_number    Table2_content
0     A                 123             B
1     C                 456             
2     D                 789             B
3     A                 012             E
6     F                 345             
7     C                 678             E
8     A                 123             
9     A                 123             E
10    C                 456             B
11    C                 456             E
12    C                 456             B
13    C                 123             
14    C                 123             B
ID    ID_to_part1    model_number    ID_to_part2
8     0              123             
0     0              123             0
9     0              123             1
13    1              123             
14    1              123             0
1     1              456             
10    1              456             0
12    1              456             0
11    1              456             1
ID    ID_to_part1    model_number    ID_to_part2
10    1              456             0
12    1              456             0
问题2 如果第三部分也匹配,则唯一索引的前两部分可以“破坏”所需唯一索引的行/元组。换句话说,其他行不是威胁(查询1减去查询2)

结果:

ID    Table3_content    model_number    Table2_content
0     A                 123             B
1     C                 456             
2     D                 789             B
3     A                 012             E
6     F                 345             
7     C                 678             E
8     A                 123             
9     A                 123             E
10    C                 456             B
11    C                 456             E
12    C                 456             B
13    C                 123             
14    C                 123             B
ID    ID_to_part1    model_number    ID_to_part2
8     0              123             
0     0              123             0
9     0              123             1
13    1              123             
14    1              123             0
1     1              456             
10    1              456             0
12    1              456             0
11    1              456             1
ID    ID_to_part1    model_number    ID_to_part2
10    1              456             0
12    1              456             0
问题3 “断开”所需唯一索引的行/元组

SELECT "Table1".*
    FROM "Table1"
        JOIN (
            SELECT "ID_to_part1", "model_number", "ID_to_part2"
                FROM "Table1"
                GROUP BY "ID_to_part1", "model_number", "ID_to_part2"
                HAVING COUNT(*) > 1
        ) AS "non_unique_model"
            ON "Table1"."ID_to_part1"="non_unique_model"."ID_to_part1"
                AND "Table1"."model_number"="non_unique_model"."model_number"
                AND "Table1"."ID_to_part2"="non_unique_model"."ID_to_part2"
    ORDER BY "ID_to_part1" ASC, "model_number" ASC, "ID_to_part2" ASC, "ID" ASC
结果:

ID    Table3_content    model_number    Table2_content
0     A                 123             B
1     C                 456             
2     D                 789             B
3     A                 012             E
6     F                 345             
7     C                 678             E
8     A                 123             
9     A                 123             E
10    C                 456             B
11    C                 456             E
12    C                 456             B
13    C                 123             
14    C                 123             B
ID    ID_to_part1    model_number    ID_to_part2
8     0              123             
0     0              123             0
9     0              123             1
13    1              123             
14    1              123             0
1     1              456             
10    1              456             0
12    1              456             0
11    1              456             1
ID    ID_to_part1    model_number    ID_to_part2
10    1              456             0
12    1              456             0
美化重要表模式
欢迎来到SO!我觉得你的问题有点难理解

编辑:

表1中有记录。对于表1中的每条记录,表2中有零条或一条对应的记录

此模式类似于表继承

进一步解释:

这将允许您必须保存以下数据

id   data1         id  data2
----------         ---------
 0    1234          0     42
 1    5678          2     57
 2    9012
请参见表1中ID为0和2的记录在表2中有相应的记录。id为1的记录不存在

附言

请注意,您还可以将内容合并到一个表中。这是否明智取决于你的情况

CREATE TABLE table1 (
    id INTEGER NOT NULL PRIMARY KEY,
    data1 INTEGER NOT NULL,
    data2 INTEGER NULL
);
我想创建一个唯一的密钥,但似乎无法创建密钥 其中包括可能包含null的列

我的理解是,您有一个FK,希望在其上构建索引以提高性能,并且该FK可能包含空值(如@Paul Draper的解决方案)

我不是HSQLDB方面的专家,但在“约束”一节中,我说: 自1.7.2版以来,唯一约束和索引对空值的行为已更改为符合SQL标准。任何唯一约束列的值为空的行始终可以添加到表中。因此,如果其中一个值为空,则多行可以包含唯一列的相同值

我理解这意味着您可以在数据库版本1.7.2中的FK上建立索引,即使列conain行的FK值为空。

您的问题是:

我不想要一个 在第一张桌子的重要部分复制,所以我想 创建一个唯一的密钥,但似乎无法创建 包括可能包含null的列

您不希望表1中的“重要部分”重复,但不清楚哪些部分必须是唯一的。假设“重要部分”是以下三列中的一部分:

"ID_to_part1" INTEGER,"model_number" VARCHAR_IGNORECASE(3) NOT NULL,"ID_to_part2" INTEGER
A) 如果您在“model_number”上创建了唯一约束,根据定义,该约束不为空:

CONSTRAINT UNIQUE ("model_number")
然后,型号编号值是唯一的,但两个不同的型号可以具有相同的编号