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 为我用有意义的名称创建的索引提供了奇怪的名称的主要内容,如果未能解决你的问题,请参考以下文章

使用实体框架的导航属性的有意义的名称

第二章 有意义的命名

如何为ListBox项提供有意义的名称

bash:有意义的唯一 id 生成

代码整洁之道第二章——有意义的命名

在 IOS 上将 RSSI BLE 值转换为更有意义的值