删过的渠道名想重新使用,怎样只限制仍在用的名称唯一
需要允许归档名称再次使用时,可以只对仍活跃的行建立唯一部分索引。租户与名称一起进入唯一键,归档记录继续保留;恢复历史行时也必须重新面对活跃重名冲突。
明确名称复用与审计历史需求
普通的UNIQUE(tenant,name)会把历史归档行也算在内,导致删过的名字一直不能再建。直接去掉唯一约束又会允许两个活跃渠道同名。部分索引的WHERE条件定义哪些行参加唯一性判断,应与列表查询、恢复操作使用的活跃定义一致,避免一处按NULL判断、另一处按空字符串判断。
演示全表唯一索引的冲突
演示先创建A租户的blue,再尝试同租户活跃重名,数据库拒绝。将第一条deleted_at设为演示时间后,A可以创建新的blue,B也可独立使用同名。此时恢复第一条会再次冲突,程序把它记录为预期失败,而不是悄悄覆盖新渠道或删掉历史。
索引的WHERE条件仅决定哪些记录参与索引,查询活跃列表时仍应显式写相同的活跃筛选。历史行不会因为离开索引而被自动隐藏。若名称比较有大小写、空格归一或排序规则要求,也要在设计时明确;blue与其他拼写是否算同名,不能由管理员在恢复时临时决定。
核心表达式(完整建表与输入见附件):
CREATE UNIQUE INDEX active_name ON channels(tenant,name)
WHERE deleted_at IS NULL;
说明SQLite版本及其他数据库方言
恢复界面需要把冲突解释给管理员:更名、保持归档或先处理当前活跃项,是业务决策。不要捕获唯一异常以后无条件改成更新现有行,否则“恢复历史配置”会变成“覆盖另一条配置”。这些字段是演示设计,迁移现有库前要核对它实际的删除语义。
适用范围:仅SQLite合成表;归档字段与策略是本文设计,不写成New API恢复接口保证。
配套样本与复核入口
- run.py:独立运行程序,包含合成输入、操作和正反例断言。
- case.json:输入说明、预期任务与适用范围,便于保存和交接。
- observed.json:本次实际执行输出;临时路径、进程号和计时可能随运行变化。
运行输出保留三条历史记录,第一条已经归档,第二条与第三条属于不同租户的活跃项。先核对active_duplicate_rejected,再核对restore_conflict,两者均应为真。不要通过删除第一条来让测试通过,那样会把历史保留问题绕掉。迁移自己的设计时,也要加入同租户恢复、跨租户同名以及归档时间为空的组合。
Python3.8以上及标准库;使用Python自带SQLite。程序不读取现有网关数据库,全部样本写入内存或新建临时目录,执行完自动清理;没有任何模型API调用。
python -B run.py
阅读输出时,先按case.json中的任务逐项核对网关软删除唯一索引,再与observed.json比较。非零退出表示依赖或断言需要处理,应保留实际错误。
一手依据1(WHERE限定参与索引的行,可建立唯一部分索引;不是所有行一律唯一。)。
继续阅读:批量导入渠道到第三行失败,怎样按既定策略保留成功项或整批回滚;两名管理员先后保存渠道配置,怎样阻止旧页面覆盖新修改;模型别名重复或成环,怎样在网关启动前用离线表检查。
不想自己搭网关、自己维护渠道?
力达云是托管的 OpenAI / Anthropic 双格式端点,一期提供 DeepSeek,注册送 ¥5 额度。