自定义设计
那封改变一切的邮件 💬
那天早上,我像往常一样打开邮箱,准备处理用户的反馈邮件。大多是些”链接打不开”、“访问速度慢”之类的问题,我已经习惯了。
但有一封邮件让我停下了手头的动作。
发件人:Nike Digital Team 主题:关于您的短链接服务
您好,
我们在社交媒体上看到很多用户在使用您的短链接服务,效果很好。
我们有一个商业需求:我们希望获得 short.url/nike 这样的品牌短链接。 我们的产品链接会定期更新,但短链接可以保持不变,这样在广告投放时更加稳定。
关于价格,我们可以接受按月或按年付费。请告知您的合作方式。
期待您的回复。
—— Nike Digital Team
我的心跳突然加速了。
付费? 这是我的短链接服务第一次有人主动提出要付费!
我立刻意识到:这不是一个简单的功能需求,这是一个商业机会。
自定义短链接——这三个字在我脑海中闪烁。用户想要自己定义的短链接后缀,而不是系统生成的随机字符。
这不仅仅是个技术问题,这是个产品设计问题。我需要设计一套完整的自定义别名系统。
定义规则:什么别名是合法的?📋
我开始思考第一个问题:什么样的自定义别名应该被允许?
如果允许用户输入任意字符,可能会出现安全问题、URL冲突问题、甚至是系统路径混乱的问题。
我拿出一张纸,开始画规则边界:
┌─────────────────────────────────────────────┐
│ 自定义别名验证规则 │
├─────────────────────────────────────────────┤
│ 1. 长度限制:3-30个字符 │
│ 2. 字符集:字母、数字、连字符、下划线 │
│ 3. 保留词:系统保留的敏感词汇 │
│ 4. 重复检查:不能与现有别名冲突 │
│ 5. 敏感词过滤:不当词汇拦截 │
└─────────────────────────────────────────────┘规则1:长度限制
为什么不能太短?
长度 < 3字符:
- 组合太少(26个字母 × 26个字母 = 676种)
- 很容易冲突
- 不够有意义
- 容易与系统路径混淆为什么不能太长?
长度 > 30字符:
- 失去短链接的意义
- 用户体验差
- 违背了"短"的初衷
- 可能超过某些系统的URL长度限制我先把验证规则写清楚:
落地思路
- 这里省略具体语法,只保留设计层面的职责边界。
- 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。
规则2:字符集限制
允许哪些字符?
我查阅了RFC 3986(URL规范),发现URL路径段中安全使用的字符包括:
- 字母:a-z, A-Z
- 数字:0-9
- 连字符:-
- 下划线:_
- 点号:.(但我不想使用,因为看起来像文件扩展名)
不允许哪些字符?
× 空格:会被编码成 %20,破坏短链接的简洁性
× 中文/日文等非ASCII字符:需要编码,变长
× 特殊字符:/、?、&、#、@等都有URL特殊含义
× 控制字符:可能破坏系统
× 表情符号:编码后极长我继续把字符规则写清楚:
落地思路
- 这里省略具体语法,只保留设计层面的职责边界。
- 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。
规则3:保留词检查
这是最棘手的部分。我需要确保用户不能注册与系统路径冲突的别名。
我列出了第一版保留词清单:
落地思路
- 这里省略具体语法,只保留设计层面的职责边界。
- 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。
规则4:重复检查
即使别名通过了所有验证规则,我还必须确保它没有被其他用户使用。
落地思路
- 这里省略具体语法,只保留设计层面的职责边界。
- 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。
规则5:敏感词过滤
最后一个安全网:防止用户注册不当的别名。
落地思路
- 这里省略具体语法,只保留设计层面的职责边界。
- 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。
完整的验证器 🔍
现在我把所有规则整合成一个完整的验证器:
落地思路
- 这里省略具体语法,只保留设计层面的职责边界。
- 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。
数据库设计:自定义别名需要独立存储 💾
我意识到自定义别名和自动生成的短码是两个不同的体系:
自动生成的短码:
- 长度固定(如6字符)
- 字符集固定(Base62)
- 无特殊含义
- 冲突概率极低
自定义别名:
- 长度不固定(3-30字符)
- 字符集宽松但有限制
- 有商业价值
- 冲突概率较高这意味着我需要设计一个新的表结构,而不是简单地复用现有的urls表。
设计方案1:扩展现有表
数据设计要点
- 这是一次表结构演进:随着链接管理能力增加,把新状态、新时间点或新归属关系补进数据模型。
- 索引服务于高频查询,重点关注
idx_custom_alias。
优点:
- 改动最小
- 查询简单(一张表)
缺点:
- 字段冗余(
short_code和custom_alias) - 不够清晰(自定义和自动生成的混在一起)
设计方案2:独立表(我选择这个)
数据设计要点
- 核心是在
custom_aliases里保存业务事实,而不是把规则散落在应用逻辑里。- 写入时要保证短码唯一、字段完整,并为后续查询留下必要状态。
- 更新操作通常意味着链接状态变化,要同步考虑缓存刷新和审计记录。
- 关键字段包括
id、user_id、custom_alias、long_url、created_at、updated_at、word、reason,它们决定了后续查询和管理能力。
优点:
- 职责清晰
- 易于扩展(比如未来要给自定义别名加更多属性)
- 便于审计和历史追踪
缺点:
- 查询时需要JOIN两张表(但这个场景很少)
我选择了方案2。
冲突处理:两个人都想要 ‘nike’ 怎么办?⚡
这是一个真实的问题:如果有两个商家都想注册 nike 这个别名,应该给谁?
我设计了一个”先到先得”的机制,配合事务保证原子性:
落地思路
- 这里省略具体语法,只保留设计层面的职责边界。
- 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。
并发安全
在高并发场景下,两个用户可能同时注册同一个别名。我需要确保只有一个人能成功。
落地思路
- 这里省略具体语法,只保留设计层面的职责边界。
- 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。
用户体验:实时可用性检查 🎨
我花了两天时间优化一个细节:当用户输入自定义别名时,实时显示它是否可用。
这需要前端的防抖(debounce)和后端的高效验证配合。
前端实现
落地思路
- 这里省略具体语法,只保留设计层面的职责边界。
- 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。
后端API
落地思路
- 这里省略具体语法,只保留设计层面的职责边界。
- 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。
这个交互细节花了两天时间,但效果很好——用户可以立即知道他们想要的别名是否可用,避免了填写完表单后才发现别名被占用的挫败感。
上线第一天:有人注册了50个品牌名 🚨
自定义别名功能上线了。
我满怀期待地打开后台监控,看看有没有人会使用这个新功能。
第一天结束时,我看到了一些数据:
自定义别名注册数量:127个
最热门的别名:
- nike (1次)
- adidas (1次)
- apple (1次)
- samsung (1次)
- test (3次)
- mylink (5次)
- brand123 (2次)看起来还好。
但当我深入查看时,发现了一个问题:有一个用户注册了50个知名品牌的别名。
用户 ID: 18472
注册的别名:
- nike
- adidas
- puma
- reebok
- newbalance
- converse
- asics
- saucony
- ...
(共50个运动品牌名)更糟糕的是,这些别名指向的URL都是一些不知名的电商网站,很明显是抢注行为。
我意识到:这需要防抢注机制。
问题:
- 恶意用户可以批量注册大量品牌名
- 真正的品牌所有者反而无法使用自己的品牌名
- 这可能导致法律纠纷
- 破坏了平台的公信力
我需要解决:
- 限制每个用户的注册数量
- 实施品牌名验证机制
- 建立申诉流程
- 考虑引入付费门槛
这些,将是下一节的内容。
本节小结 📝
完整的别名验证流程
用户输入别名
↓
【规则1】长度检查(3-30字符)
↓
【规则2】字符检查(字母、数字、-、_)
↓
【规则3】保留词检查(系统路径)
↓
【规则4】敏感词检查(不当词汇)
↓
【规则5】重复检查(数据库查询)
↓
【规则6】冲突处理(事务保证)
↓
创建成功 ✅核心能力拆解
| 组件 | 职责 |
|---|---|
CustomAliasValidator | 完整的别名验证器 |
AliasCharacterValidator | 字符规则验证 |
ReservedWordChecker | 保留词检查 |
ProfanityFilter | 敏感词过滤 |
custom_aliases 表 | 存储自定义别名 |
reserved_words 表 | 存储保留词 |
数据库表结构
数据设计要点
- 更新操作通常意味着链接状态变化,要同步考虑缓存刷新和审计记录。
想一想
问题1:品牌验证
Nike团队真的注册了nike这个别名,还是被抢注者抢占了?
提示
考虑:
- 如何验证用户真的是品牌所有者?
- 是否需要上传商标证书?
- 是否需要企业认证?
- 未认证用户是否允许注册品牌名?
我们将在下一节讨论这个问题。
问题2:批量注册防护
如何防止一个用户在短时间内注册大量别名?
提示
考虑:
- 限制每个用户的注册数量(如10个)
- 限制注册频率(如每小时最多5个)
- 短别名(3-4字符)需要额外审核
- 引入付费门槛(减少恶意注册)
问题3:历史遗留
如果某个别名被抢注了,真正的品牌所有者怎么办?
提示
考虑:
- 是否可以强制转移别名?
- 是否需要建立申诉流程?
- 如何证明所有权?
- 是否需要仲裁机制?
(下一节:抢注防护与品牌验证)