我使用/贡献了一个Haskell库(持久性)来为Postgres生成迁移。该库通过读取Haskell数据类型来工作,然后生成与这些类型匹配的适当表。
它是通过查看基于Haskell类型的预期数据库模式(即,名为Settings
的Haskell记录意味着应创建名为settings
的表)来完成此操作的,然后将其与其中的内容进行比较Postgres(如果没有名为settings
的表,它将执行迁移以创建该表)。
不幸的是,当Postgres截断标识符时,这不能很好地工作,如Postgres docs中所述,标识符的字符数为63。给出一些类似的SQL:
CREATE TABLE an_extremely_fantastically_super_long_name_child(an_extremely_fantastically_super_long_name_parent_id INTEGER NOT NULL REFERENCES an_extremely_fantastically_super_long_name_parent);
CREATE TABLE my_massively_huge_biggest_child_table (biggest_ever_column_name_that_will_reference_a_parent INTEGER NOT NULL REFERENCES an_extremely_fantastically_super_long_name_parent);
它将产生一个名为my_massively_huge_biggest_chi_biggest_ever_column_name_tha_fkey
的外键约束(删除表名的一部分和列名的一部分并添加_fkey
)。
我可以让Haskell库将要创建的所有标识符截断为63个字符,这将解决问题。但是,我想与Postgres使用REFERENCES
语法生成的内容保持兼容性。为此,我需要复制Postgres中使用的算法。这是什么算法?我尝试在Postgres源代码中进行搜索,但是由于Postgres是一个非常庞大的项目,因此很难找到。
我认为,如果我给它足够的示例数据,我可以算出确切的公式,但是也可以只看一下源代码。
答案 0 :(得分:1)
~postgresql/src/backend/commands/indexcmds.c
#2000行之后:ChooseIndexName()
和朋友。
[这是用于索引,但是其他生成的名称的方法与此类似]