关于开发日志功能操作人存储user表的主键id还是字符串name

文章探讨了在存储用户信息时,使用用户ID与用户名的优缺点。存储ID避免了因用户修改名字导致日志中的操作人信息变化,但当用户被删除时,日志可能无法正常显示。反之,存储用户名方便日志展示,但易受用户修改影响。提出的解决方案包括在删除用户时处理日志中的相关操作,或者利用软删除技术。更新提到,使用软删除可以解决这一问题,但在查询日志时需要注意处理软删除状态。

对比 存储id和存储name

优点:(存储id的优点,存储name的缺点)
1、用户修改name字段时,日志中的操作人name会跟着变化
缺点: (存储id的缺点,存储name的优点)
1、删除user表中的该用户后,日志表中无法正常显示操作人

想到的解决方案

1、不管(针对上述对比会造成相应的问题)
2、删除用户时,判断日志中是否有该用户的操作,如果有则做一些麻烦的操作(比如说日志表中是varchar类型的user_id,可以直接把name存入user_id中,然后再展示的时候如果关联表的时候没有和user_id对应的则直接展示user_id)

总结

有待后续继续更新,可以看看其他人解决方法。目前的话感觉还是得根据业务情况分析(比较简单),如果修改用户的操作很多,但是不删除用户可以采用存id,如果删除比较多,但是不支持用户对name进行修改,则使用存储name。

更新:

突然想到使用软删除就能解决这个问题,在日志操作的操作人处存储user的id,然后在使用left join查询的时候不启用软删除即可(不过得主要如果有软删除的情况下不能用数据库自带的唯一索引来进行校验)
<think>我们根据用户需求创建。用户要求创建名为users的,包含以下字段: - id: 使用UUID类型作为主键 - user_name: 字符串类型 - user_no: 可能是用户编号,字符串或数字类型,但未明确,这里根据常见情况设为字符串类型 根据引用[1]和引用[3],我们可以使用BINARY(16)来存储UUID,并使用MySQL的UUID()函数生成UUID,但插入时需要使用UNHEX(REPLACE(UUID(), '-', ''))来存储为16字节二进制,以提高性能。 另外,引用[3]也提到,直接使用VARCHAR(36)存储UUID字符串也是可行的,但占用空间较大,且查询效率不如二进制。 因此,我们有两种方案: 方案1:使用BINARY(16)存储UUID(16字节),性能较好。 方案2:使用CHAR(36)或VARCHAR(36)存储字符串形式的UUID(36字节),可读性好。 由于用户没有明确要求,但作为主键,性能很重要,推荐使用BINARY(16)。 步骤: 1. 创建时,定义id字段为BINARY(16),并设置为主键。 2. 定义user_name字段,根据需求,使用VARCHAR类型,长度根据实际需要设定(这里用户没有指定,我们假设为255)。 3. 定义user_no字段,可能是用户编号,可以是数字或字符串。由于用户编号通常包含字母和数字(如工号、学号),我们使用VARCHAR类型,长度设为50(可根据实际调整)。 创建的SQL语句: ```sql CREATE TABLE users ( id BINARY(16) PRIMARY KEY, user_name VARCHAR(255) NOT NULL, user_no VARCHAR(50) NOT NULL ); ``` 插入数据时,为了生成UUID并转换为二进制存储,可以这样写: ```sql INSERT INTO users (id, user_name, user_no) VALUES (UNHEX(REPLACE(UUID(), '-', '')), '张三', 'U001'); ``` 注意:UUID()生成的是带连字符的36位字符串,通过REPLACE去掉连字符,然后用UNHEX将其转换为16字节的二进制数据。 如果用户希望使用自增整数作为主键(如引用[2]和引用[4]所示),但用户明确要求使用UUID,所以这里不使用自增。 另外,如果已经存在,我们需要先删除,但用户没有要求,所以直接创建。 如果用户需要可读的UUID字符串,也可以使用CHAR(36)存储,但性能不如二进制: ```sql CREATE TABLE users ( id CHAR(36) PRIMARY KEY DEFAULT (UUID()), user_name VARCHAR(255) NOT NULL, user_no VARCHAR(50) NOT NULL ); ``` 这样插入时可以不用指定id,默认会生成一个UUID字符串。但是,用户要求的是UUID作为主键,且没有指定存储形式,我们优先推荐二进制存储。 因此,最终选择第一种方式(BINARY(16))来创建。 注意:使用BINARY(16)存储UUID,在查询时如果需要可读形式,可以使用HEX函数将id转换为十六进制字符串,但注意转换后是32位字符串(不带连字符)。如果需要带连字符的格式,则需要使用字符串处理函数。 示例查询: ```sql SELECT HEX(id) as id, user_name, user_no FROM users; ``` 结果中的id是32位的十六进制字符串(如:'AAB5D5FD70C111E5A4FBB026B977EB28')。如果需要原来的UUID格式,可以使用: ```sql SELECT CONCAT( SUBSTR(HEX(id), 1, 8), '-', SUBSTR(HEX(id), 9, 4), '-', SUBSTR(HEX(id), 13, 4), '-', SUBSTR(HEX(id), 17, 4), '-', SUBSTR(HEX(id), 21) ) AS id, user_name, user_no FROM users; ``` 但这样查询效率会降低。因此,如果经常需要可读形式,可以考虑存储为CHAR(36)类型,但占用空间更大,索引效率也会降低。 根据性能考虑,我们建议使用BINARY(16),并在应用层需要显示的时候再转换。 综上所述,创建的语句为: ```sql CREATE TABLE users ( id BINARY(16) PRIMARY KEY, user_name VARCHAR(255) NOT NULL, user_no VARCHAR(50) NOT NULL ); ``` 插入数据时使用: ```sql INSERT INTO users (id, user_name, user_no) VALUES (UNHEX(REPLACE(UUID(), '-', '')), '张三', 'U001'); ``` 如果同时插入多行,每行都需要调用UUID()函数,注意每行都会生成不同的UUID。 另外,为了确保user_no的唯一性,用户可能需要添加唯一约束,但题目没有要求,所以这里不添加。 如果用户需要,可以添加: ```sql ALTER TABLE users ADD UNIQUE (user_no); ``` 或者在创建时直接添加: ```sql CREATE TABLE users ( id BINARY(16) PRIMARY KEY, user_name VARCHAR(255) NOT NULL, user_no VARCHAR(50) NOT NULL UNIQUE ); ``` 这样user_no就不能重复。 考虑到用户没有明确要求,我们可以在创建时先不加唯一约束,如果需要后续再加。 因此,最终创建语句为: ```sql CREATE TABLE users ( id BINARY(16) PRIMARY KEY, user_name VARCHAR(255) NOT NULL, user_no VARCHAR(50) NOT NULL ); ``` 如果已经存在,可以先删除(如果确定可以删除): ```sql DROP TABLE IF EXISTS users; ``` 然后执行创建。 所以完整脚本: ```sql DROP TABLE IF EXISTS users; CREATE TABLE users ( id BINARY(16) PRIMARY KEY, user_name VARCHAR(255) NOT NULL, user_no VARCHAR(50) NOT NULL ); ``` 注意:在生产环境中,删除要谨慎,确保数据已经备份或不再需要。 如果只是创建,不删除已存在的,则去掉DROP TABLE语句。 根据用户需求,我们提供创建的语句即可。 最后,生成相关问题。</think>根据您的需求,我将创建一个使用 UUID 作为主键的 `users` ,包含指定字段和主键约束。以下是完整的 MySQL 创建语句: ```sql CREATE TABLE users ( id BINARY(16) PRIMARY KEY DEFAULT (UNHEX(REPLACE(UUID(), '-', ''))), user_name VARCHAR(255) NOT NULL, user_no VARCHAR(50) NOT NULL UNIQUE ); ``` ### 字段说明: 1. **`id` 字段**: - 使用 `BINARY(16)` 类型高效存储 UUID(16字节) - 设置为主键 `PRIMARY KEY` - 默认值:`DEFAULT (UNHEX(REPLACE(UUID(), '-', '')))` - `UUID()` 生成标准 UUID 字符串 - `REPLACE(UUID(), '-', '')` 移除连字符 - `UNHEX()` 转换为二进制格式[^1][^3] 2. **`user_name` 字段**: - 使用 `VARCHAR(255)` 类型 - `NOT NULL` 约束确保必须有值 3. **`user_no` 字段**: - 使用 `VARCHAR(50)` 类型 - `NOT NULL` 约束确保必须有值 - `UNIQUE` 约束确保用户编号唯一 ### 插入数据示例: ```sql -- 不指定 id (自动生成 UUID) INSERT INTO users (user_name, user_no) VALUES ('张三', 'U2023001'); -- 手动指定 UUID INSERT INTO users (id, user_name, user_no) VALUES (UNHEX(REPLACE('a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11', '-', '')), '李四', 'U2023002'); ``` ### 查询 UUID 数据: ```sql -- 将二进制 ID 转换为可读格式 SELECT LOWER(CONCAT( HEX(SUBSTR(id, 1, 4)), '-', HEX(SUBSTR(id, 5, 2)), '-', HEX(SUBSTR(id, 7, 2)), '-', HEX(SUBSTR(id, 9, 2)), '-', HEX(SUBSTR(id, 11)) )) AS uuid, user_name, user_no FROM users; ``` ### 设计优势: 1. **UUID 主键**:全局唯一标识符,适合分布式系统[^1][^3] 2. **存储优化**:二进制存储比 VARCHAR(36) 节省 56% 空间[^3] 3. **性能优化**:固定长度 BINARY(16) 比变长 VARCHAR 索引效率更高 4. **唯一约束**:确保 `user_no` 不重复 ### 注意事项: 1. 使用 `BINARY(16)` 时,查询需用 `HEX()` 函数转换显示 2. 自增 ID 方案(如引用[2][^4])更简单,但 UUID 在分布式系统中更可靠 3. 如需修改现有结构(如添加自增ID),可使用 `ALTER TABLE`(参考引用[5][^5])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值