Hsqldb 重命名具有相同父项的重复项

Posted

技术标签:

【中文标题】Hsqldb 重命名具有相同父项的重复项【英文标题】:Hsqldb rename duplicates of item names with same parent 【发布时间】:2019-03-01 06:37:55 【问题描述】:

我编写了一个 LibreOffice / OpenOffice 扩展程序,允许访问这些 Google Drive 文件。

为此,我使用 Hsqldb 2.4 数据库,script file is accessible at: https://github.com/prrvchr/gDriveOOo/blob/master/gDriveOOo/hsqldb/vnd.google-apps.script

LibreOffice / OpenOffice UNO API 不处理重复的文件名(例如在文件系统下),而 Google Drive 提供了这种可能性。

为了解决这个问题,我创建了四个视图('ChildUri'、'IdentifierUri'、'ItemUri' 和 'Uri'),允许我构建一个新的表单名称:CONCAT (name, ~, position) for第二个和后面的 doublon,位置是它们在 GROUP BY 子句中的位置...

CREATE VIEW PUBLIC."ChildUri" ("Id","Name","Parent") AS SELECT "I"."Id","I"."Name","C"."ItemId" FROM PUBLIC."Items" AS "I" JOIN PUBLIC."Children" AS "C" ON "I"."Id"="C"."ChildId"  WHERE "I"."Trashed"=FALSE

CREATE VIEW PUBLIC."IdentifierUri" ("Idx","Name","Parent") AS SELECT ARRAY_AGG("I"."Id" ORDER BY "I"."DateCreated","I"."Id"),"I"."Name","C"."Parent" FROM PUBLIC."Items" AS "I" JOIN PUBLIC."ChildUri" AS "C" ON "I"."Id"="C"."Id" GROUP BY "I"."Name","C"."Parent"

CREATE VIEW PUBLIC."ItemUri" ("Id","Name","Length","Position","Parent") AS SELECT "C"."Id","I"."Name",CARDINALITY("I"."Idx"),POSITION_ARRAY("C"."Id" IN "I"."Idx"),"I"."Parent" FROM PUBLIC."ChildUri" AS "C" JOIN PUBLIC."IdentifierUri" AS "I" ON "C"."Name"="I"."Name" AND "C"."Parent"="I"."Parent"

CREATE VIEW PUBLIC."Uri" ("Id","Name","Uri","Parent") AS SELECT "I"."Id","I"."Name",CASEWHEN("I"."Position"=1,"I"."Name",INSERT("I"."Name", LENGTH("I"."Name") - POSITION('.' IN REVERSE("I"."Name")) + 1,0,CONCAT('~',"I"."Position"))),"I"."Parent" FROM PUBLIC."ItemUri" AS "I"

它运行良好,但在调用“selectChild”过程时速度极慢,执行需要 10 秒,而之前只需要几秒钟。

CREATE PROCEDURE PUBLIC."selectChild"(IN USERID VARCHAR(100),IN ITEMID VARCHAR(100),IN URL VARCHAR(250),IN MODE SMALLINT,OUT ROWCOUNT SMALLINT) SPECIFIC "selectChild_1" LANGUAGE SQL NOT DETERMINISTIC READS SQL DATA NEW SAVEPOINT LEVEL DYNAMIC RESULT SETS 1 BEGIN ATOMIC DECLARE TMPCOUNT SMALLINT DEFAULT 0;DECLARE RESULT CURSOR WITH RETURN FOR SELECT "Title","Size","DateModified","DateCreated","IsFolder",CASEWHEN("IsFolder",CONCAT(URL,'/',"Id"),CONCAT(URL,'/',"Uri"))"TargetURL",FALSE "IsHidden",FALSE "IsVolume",FALSE "IsRemote",FALSE "IsRemoveable",FALSE "IsFloppy",FALSE "IsCompactDisc" FROM PUBLIC."Child" WHERE "UserId"=USERID AND "Parent"=ITEMID AND("IsFolder" OR "Loaded">=MODE)FOR READ ONLY;CALL "countChild"(USERID,ITEMID,MODE,TMPCOUNT);SET ROWCOUNT=TMPCOUNT;OPEN RESULT;END

我承认这超出了我的能力,向你寻求帮助。

提前致谢。

【问题讨论】:

【参考方案1】:

fredt,很高兴是你回答...找不到更好的...

我承认索引管理一定很惨。

所以我修改了基础表(用户、标识符、功能、子项)以添加唯一约束和外键约束。我混淆了 UNIQUE INDEX 和 UNIQUE CONSTRAINT...

CREATE CACHED TABLE PUBLIC."Users"("Id" VARCHAR(100) NOT NULL PRIMARY KEY,"UserName" VARCHAR(100) NOT NULL,"DisplayName" VARCHAR(100),"RootId" VARCHAR(100) NOT NULL,"TimeStamp" TIMESTAMP DEFAULT CURRENT_TIMESTAMP(3) NOT NULL,CONSTRAINT "UniqueUserName" UNIQUE ("UserName"))
CREATE CACHED TABLE PUBLIC."Identifiers"("Id" VARCHAR(100) NOT NULL PRIMARY KEY,"UserId" VARCHAR(100) NOT NULL,"TimeStamp" TIMESTAMP DEFAULT CURRENT_TIMESTAMP(3) NOT NULL,CONSTRAINT "ForeignIdentifiersUsers" FOREIGN KEY ("UserId") REFERENCES "Users"("Id"))
CREATE CACHED TABLE PUBLIC."Children"("ChildId" VARCHAR(100) NOT NULL,"ItemId" VARCHAR(100) NOT NULL,"TimeStamp" TIMESTAMP DEFAULT CURRENT_TIMESTAMP(3) NOT NULL,CONSTRAINT "UniqueChildItem" UNIQUE ("ChildId", "ItemId"),CONSTRAINT "ForeignChildrenItems" FOREIGN KEY ("ItemId") REFERENCES "Items"("Id"))
CREATE CACHED TABLE PUBLIC."Capabilities"("UserId" VARCHAR(100) NOT NULL,"ItemId" VARCHAR(100) NOT NULL,"CanAddChild" BOOLEAN DEFAULT FALSE NOT NULL,"CanRename" BOOLEAN DEFAULT FALSE NOT NULL,"IsReadOnly" BOOLEAN DEFAULT FALSE NOT NULL,"IsVersionable" BOOLEAN DEFAULT FALSE NOT NULL,"Loaded" SMALLINT DEFAULT 0 NOT NULL,"SyncMode" SMALLINT DEFAULT 0 NOT NULL,"TimeStamp" TIMESTAMP DEFAULT CURRENT_TIMESTAMP(3) NOT NULL,CONSTRAINT "ForeignCapabilitiesUsers" FOREIGN KEY ("UserId") REFERENCES "Users"("Id"),CONSTRAINT "ForeignCapabilitiesItems" FOREIGN KEY ("ItemId") REFERENCES "Items"("Id"))

我还在 VIEW Item、Child 和 VIEW 上添加了 INDEX,允许我构建新名称(ChildUri、IdentifierUri、ItemUri 和 Uri)。

我不知道我们可以把 INDEX 放在 VIEW...

CREATE INDEX "ItemIndex" ON "Item"("UserId", "Id")
CREATE INDEX "ChildUriIndex" ON "ChildUri"("Id","Parent")
CREATE INDEX "IdentifierUriIndex" ON "IdentifierUri"("Idx","Parent")
CREATE INDEX "ItemUriIndex" ON "ItemUri"("Id","Parent")
CREATE INDEX "UriIndex" ON "Uri"("Id","Parent")
CREATE INDEX "ChildIndex" ON "Child"("UserId", "Parent")

我在 Items 表中保留了索引“TrashedIndex”和“MimeTypeIndex”,这些列出现在 WHERE 子句中

CREATE INDEX "TrashedIndex" ON PUBLIC."Items"("Trashed")
CREATE INDEX "MimeTypeIndex" ON PUBLIC."Items"("MimeType")

“selectChild”请求现在在几秒钟内完成,但我不确定我的索引...我认为我有多余或丢失,或者我很幸运...

再次感谢。

编辑: 经过几次性能测试,显然只有底层表级别的 CONSTRAINT UNIQUE 和 FOREIGN KEY 提高了性能,VIEW 上的 INDEX 并没有提高查询,或者在没有性能测试工具的情况下不知不觉。

【讨论】:

【参考方案2】:

您需要一个索引来提高对表的 SELECT 查询速度。过程中的 SELECT 如果还不是 FOREIGN KEY,则需要如下索引

CREATE INDEX "ChildIndex" ON "Child"("Parent", "UserId")

【讨论】:

以上是关于Hsqldb 重命名具有相同父项的重复项的主要内容,如果未能解决你的问题,请参考以下文章

python 用于url的Python下载器,如果重复文件具有可选的重复重命名,则输出路径。

具有相同列名的命名查询内部连接表的重复数据/值

让 git 忽略重命名 [重复]

redis键重命名

如何找到跨文件重命名和重新排序添加特定 Gradle 构建依赖项的 Git 提交?

重命名非常大的 CSV 数据文件的列 [重复]