痛点
教主苦 Oracle 久矣。
目前的数仓方案是 Oracle,最近又频繁出一些百十来个业务字段的 CSV 需要在 ODS 建表,即便在字段尽可能简写的情况下还是很难控制在 30 个字符以内,故不得已尝试使用拼音命名。
采用翻译命名时,已经尽可能地做了省略和简写(包括但不限于 “不依词性、但凭词长” + “省略” + “颠倒是非” + “瞎 JB 翻译”),越说越对不起······但即便如此,还是很容易产生命名冲突或者超出 30 字符限制。
在视 “除非约定俗成否则不做任何缩写” 的原则而不见的情况下,倘若遵循首尾字母、前 4 个字母、重读音字母等缩写规律倒也容易接受。比如 “服务” 缩写成 svc
也无可厚非。但是像把 “二叉树” 缩写成 biTree
的,但凡少一个 i
又或者多一个 n
也不至于化身祖安人士!
解决方案
首先在假设所有业务字段都是名词性质,而且字段没有重复,而且字段名没有 30 个字符限制的情况下,“中心语对齐”(比如 xxx_noun
或者 noun_of_xxx
又或者 xxx_noun_for_xxx
等格式)或许也容易接受。
但是条件它不允许啊,且不说有没有 30 个字符限制,业务字段能不能保证是不重复的名词都不一定······
与其 “半吊子” 英语命名,反复纠结用哪个单词、哪个词性、哪个定语、哪个组合规律,猜错时反复去确认表注释,还不如直接用 Hash 或者拼音来的更果断干脆些。更何况 Oracle 调整字段顺序也比较麻烦,那直接 “序号后缀” 解决命名冲突又何不乐而不为!
纠结规律?笑死!根本没有规律!
const fs = require('fs')
const path = require('path')
const pinyinPro = require('pinyin-pro')
const lodash = require('lodash')
const table = { zh: '铁塔电费明细', en: 'ods_tower_electric_fee_bill' }
function convertToColumns(table) {
const csv = fs.readFileSync(path.join(__dirname, `./${table.zh}.csv`), 'utf8')
return csv
.split(csv.indexOf('\r\n') === -1 ? '\n' : '\r\n')[0]
.split(',')
.map((it, i) => ({
zh: it,
py: `${pinyinPro.pinyin(it, { pattern: 'first', toneType: 'none' }).replace(/[^a-zA-Z0-9]/g, '')}_${i}`
}))
}
function convertToDDL(table, columns) {
return `
-- DROP TABLE ${table.en};
CREATE TABLE ${table.en} (
${columns.map(it => lodash.padEnd(it.py, 30) + ' VARCHAR2(400)').join(`,\n `)},
ctime DATE DEFAULT SYSDATE NOT NULL
);
comment on table ${table.en} is '${table.zh}';
${columns.map(it => `comment on column ${table.en}.${lodash.padEnd(it.py, 30)} is '${it.zh}';`).join('\n')}
`
}
const columns = convertToColumns(table)
const ddl = convertToDDL(table, columns)
fs.writeFileSync(path.join(__dirname, `./${table.en}.sql`), ddl)
效果:
虽说迫不得已但优点也不是没有,比如说:
- 省去了海量 “瞎 JB 翻译” 的时间
- 省去了猜错字段的反复确认注释的时间
- 省去了
xxx_code
里存xxx_name
的反复确认注释的时间 - 比序号更没有规律
- 比 Hash 更有规律
- 没有选择就是最好的选择
至于缺点只能表示:
- 身不由己
- 迫不得已
- 无可奈何
- 似曾相识