Apache Derby 为我用有意义的名称创建的索引提供了奇怪的名称
Posted
技术标签:
【中文标题】Apache Derby 为我用有意义的名称创建的索引提供了奇怪的名称【英文标题】:Apache Derby gives strange names to indices I created with meaningful names 【发布时间】:2019-05-23 07:21:35 【问题描述】:我正在使用这个 ddl 在 derby 中创建一个简单的演示表:
CREATE TABLE MY_TABLE (
SESSION_ID CHAR(36),
ATTRIBUTE_NAME VARCHAR(200),
CONSTRAINT MY_TABLE_PK PRIMARY KEY (SESSION_ID, ATTRIBUTE_NAME),
);
CREATE INDEX MY_TABLE_IX1 ON MY_TABLE (SESSION_ID);
我想在测试中验证 INDEX MY_TABLE_IX1
是否实际创建。
在线搜索我看到了两种可能的方法:
JDBC -->
使用DatabaseMetaData
我可以做一些类似的事情
metadata.getIndexInfo(null, "APP", "MY_TABLE", false, false)
遍历结果集直到我得到一行
"MY_TABLE_IX1".equals(resultSet.getString("INDEX_NAME"))
SQL -->
SELECT c.CONGLOMERATENAME, t.TABLENAME FROM SYS.SYSCONGLOMERATES c
JOIN SYS.SYSTABLES t ON c.TABLEID = t.TABLEID
WHERE c.CONGLOMERATENAME = 'MY_TABLE_IX1' AND t.TABLENAME = 'MY_TABLE'
抛开明显的(比如我还应该按列名过滤之类的东西),我遇到了一个非常奇怪的行为:
Derby 将我的 一些 索引保存为 SQL181215003216931
形式的字符串,这使我无法按名称定位这些索引,而其他索引则按我在 ddl 中指定的名称保存。
虽然我举了一个小例子,但我的实际架构相当大,如果我运行以下内容:
SELECT c.CONGLOMERATENAME, t.TABLENAME FROM SYS.SYSCONGLOMERATES c
JOIN SYS.SYSTABLES t ON c.TABLEID = t.TABLEID
WHERE c.CONGLOMERATENAME LIKE '%SQL%'
我得到了相当多的索引结果,它们以相同的方式命名(它们的不同之处在于SQL
部分之后的尾随数字),尽管我给它们中的每一个都赋予了一个有意义的名称。
我尝试在网上搜索有关此行为的信息,但结果一无所获 - 有人知道我的谜团的答案吗?SQL####
类型名称似乎没有引用我最初给出的名称,那么如何根据 my 名称定位我的索引?
这是第二个 SQL 查询的示例输出:
CONGLOMERATENAME TABLENAME
------------------------------------
SQL181215003159230 MY_TABLE
SQL181215003159240 SOME_OTHER_TABLE
SQL181215003216890 YET_ANOTHER_TABLE
并从 JDBC 执行:
TABLE_CAT|TABLE_SCHEMA|TABLE_NAME |NON_UNIQUE|INDEX_QUALIFIER|INDEX_NAME |TYPE|ORDINAL_POSITION|COLUMN_NAME|ASC_OR_DESC|CARDINALITY|PAGES|FILTER_CONDITION|
|APP |MY_TABLE |false | |SQL181224003626061|3 |1 |SESSION_ID |A |null |null |null |
|APP |SOME_OTHER_TABLE |false | |SQL181215003159240|3 |1 |SESSION_ID |A |null |null |null |
---编辑----:
根据下面@Noam 的回答,他似乎是正确的,SQL###
索引确实是主键列上设置的主键和索引(虽然这基本上是没有根据的,但这不是重点)。
我的问题仍然是我需要确定我声明的索引是否具有特定名称 - 并且找不到该名称。
【问题讨论】:
您是说使用 both 方法存在索引名称问题吗? 是的,两者都尝试了,得到了相同的结果。如果有帮助,我可以粘贴 jdbc 给出的结果集,因为结构有点不同,但索引在两者中的名称相同。 @TimBiegeleisen 编辑了帖子并粘贴了我在两种情况下得到的示例输出 为什么需要知道这些名字?我可以推测并说 Derby 希望确保每个索引始终具有唯一的名称。 @TimBiegeleisen 我需要能够确定某些模式转换是否正确运行,它会影响我的应用程序的状态。 【参考方案1】:我的问题仍然是我需要确定我声明的索引是否具有特定名称 - 并且找不到该名称。
我刚刚使用 DBeaver 和 derby-10.14.2.0.jar 进行了测试,我发现正如@Noam 提到的,“MY_TABLE_PK”列在 SYS.SYSCONSTRAINTS 中
SELECT * FROM SYS.SYSCONSTRAINTS WHERE CONSTRAINTNAME='MY_TABLE_PK'
并且“MY_TABLE_IX1”列在 SYS.SYSCONGLOMERATES 中
SELECT * FROM SYS.SYSCONGLOMERATES WHERE CONGLOMERATENAME='MY_TABLE_IX1'
【讨论】:
感谢您的回复,这有点奇怪,因为这根本不是我的情况。我确实在示例中省略了一个细节,因为我认为这并不重要,但也许确实如此:我还有一个定义为CONSTRAINT MY_TABLE_ATTR_FK FOREIGN KEY (SESSION_ID) REFERENCES SOME_OTHER_TABLE(SESSION_ID) ON DELETE CASCADE
的外键 - 也许区别就在那里..?
@danf - 确实很奇怪。添加 FK 约束后,我也可以看到它:SELECT * FROM SYS.SYSCONSTRAINTS WHERE CONSTRAINTNAME='MY_TABLE_ATTR_FK'
。是的,也创建了许多“SQL*”索引,但命名项目确实显示给我。我正在使用最新版本的 Derby 和 DBeaver,顺便说一句。【参考方案2】:
SQL*
是直接在表定义上配置的唯一/主索引,例如 MY_TABLE_PK
根据他们的文档 (https://db.apache.org/derby/docs/10.1/ref/rrefsqlj13590.html),您应该能够找到可以使用此查询的约束索引(我在那里对查询进行了细微修改):
SELECT * FROM SYS.SYSCONSTRAINTS t
JOIN SYS.SYSCONGLOMERATES c ON t.TABLEID = c.TABLEID
WHERE CONSTRAINTNAME = 'MY_TABLE_PK';
【讨论】:
正是如此。此外,请注意,“索引”在概念上和物理上都是与“约束”不同的对象。您命名的是约束,而不是索引。您也可以命名索引,但这与命名约束并让 Derby 自动为您生成支持索引不同。以上是关于Apache Derby 为我用有意义的名称创建的索引提供了奇怪的名称的主要内容,如果未能解决你的问题,请参考以下文章