(高频SQL50题)196.删除重复的电子邮箱

题目

表: Person

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| email       | varchar |
+-------------+---------+
id 是该表的主键列(具有唯一值的列)。
该表的每一行包含一封电子邮件。电子邮件将不包含大写字母。

编写解决方案 删除 所有重复的电子邮件,只保留一个具有最小 id 的唯一电子邮件。

(对于 SQL 用户,请注意你应该编写一个 DELETE 语句而不是 SELECT 语句。)

(对于 Pandas 用户,请注意你应该直接修改 Person 表。)

运行脚本后,显示的答案是 Person 表。驱动程序将首先编译并运行您的代码片段,然后再显示 Person 表。Person 表的最终顺序 无关紧要 。

返回结果格式如下示例所示。

示例 1:

输入: 
Person 表:
+----+------------------+
| id | email            |
+----+------------------+
| 1  | john@example.com |
| 2  | bob@example.com  |
| 3  | john@example.com |
+----+------------------+
输出: 
+----+------------------+
| id | email            |
+----+------------------+
| 1  | john@example.com |
| 2  | bob@example.com  |
+----+------------------+
解释: john@example.com重复两次。我们保留最小的Id = 1。

解析

将Person表连接起来,有:

比较表1和表2的id,如果表2的id大于表1,则删除表二的行,最后返回表2

解答

delete p2
from Person as p1
join Person as p2
on p1.email = p2.email and p2.id >p1.id

<think>我们正在设计一个用户表,用于支持新闻查询功能。根据引用[1]和引用[2]中的信息,我们知道这个系统可能是一个新闻管理系统,需要存储用户信息,并且用户可能需要查询新闻。同时,考虑到引用[2]中提到的新闻管理系统数据库设计,我们可以参考一些基本属性。 用户表的设计应该包含哪些字段? 1. 用户唯一标识:通常是一个自增主键(id) 2. 用户名(username):用于登录或显示 3. 密码(password):存储加密后的密码 4. 电子邮箱(email):用于联系和找回密码 5. 创建时间(created_at):记录用户注册时间 6. 更新时间(updated_at):记录用户信息更新时间 此外,根据新闻查询功能的需求,我们可能还需要考虑: 7. 角色(role):例如普通用户、编辑、管理员等,不同角色可能有不同的新闻查询权限 8. 状态(status):标记用户是否激活、禁用等 但是,请注意,用户表本身并不直接存储新闻,而是通过其他表(如新闻表)与用户关联(例如,新闻表中可能有作者id,即用户id)。因此,在查询新闻时,我们可能需要通过用户id来关联查询该用户发布的新闻,或者根据用户的角色来查询其有权限查看的新闻。 因此,设计用户表时,我们主要关注用户的基本信息,而新闻查询功能则通过关联查询来实现。 下面是一个用户表的SQL创建语句示例(以MySQL为例): ```sql CREATE TABLE `user` ( `id` INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户唯一标识', `username` VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名', `password` VARCHAR(255) NOT NULL COMMENT '加密后的密码', `email` VARCHAR(100) UNIQUE COMMENT '电子邮箱', `role` ENUM('normal', 'editor', 'admin') DEFAULT 'normal' COMMENT '用户角色:普通用户、编辑、管理员', `status` TINYINT(1) DEFAULT 1 COMMENT '状态:0-禁用,1-正常', `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表'; ``` 说明: - 将`id`设为主键,自增,确保每个用户有唯一标识。 - `username`和`email`设置唯一约束,避免重复。 - `password`字段存储加密后的密码,长度建议设置较长(如255)以兼容各种加密算法。 - `role`字段使用枚举类型,限定为几种角色,默认普通用户。 - `status`使用TINYINT,0表示禁用,1表示正常(也可以使用ENUM,但这里用0/1更简洁)。 - `created_at`和`updated_at`分别记录创建和更新时间,并设置自动更新。 关于新闻查询功能: 通常,我们会有一个新闻表(例如`news`),其中包含一个指向用户表的外键(如`author_id`),表示新闻的作者。这样,当我们需要查询某个用户发布的新闻时,可以通过`author_id`进行关联查询。 例如,新闻表可能如下设计(简略): ```sql CREATE TABLE `news` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `title` VARCHAR(100) NOT NULL COMMENT '新闻标', `content` TEXT COMMENT '新闻内容', `author_id` INT NOT NULL COMMENT '作者ID(关联user表)', `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, `updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, FOREIGN KEY (`author_id`) REFERENCES `user`(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='新闻表'; ``` 这样,当我们需要查询某个用户(比如用户id为1)发布的新闻时,可以执行: ```sql SELECT * FROM news WHERE author_id = 1; ``` 或者,如果需要根据用户名来查询,可以关联用户表: ```sql SELECT n.* FROM news n JOIN user u ON n.author_id = u.id WHERE u.username = '张三'; ``` 因此,用户表的设计主要围绕用户自身信息,而新闻查询则通过关联新闻表来实现。 注意:在实际应用中,可能还需要考虑索引(例如在`user`表的`username`和`email`上建立索引,在`news`表的`author_id`上建立外键索引)以提高查询效率。 另外,根据引用[2]中提到的新闻管理系统,可能还需要考虑用户的其他属性,如头像、个人简介等,但以上是最基本的字段。 根据需求扩展: 如果新闻查询功能需要支持按用户角色来过滤(例如只查询编辑发布的新闻),那么我们在用户表中设计的`role`字段就派上用场了。例如: ```sql SELECT n.* FROM news n JOIN user u ON n.author_id = u.id WHERE u.role = 'editor'; ``` 综上所述,我们设计了一个用户表,并说明了如何通过该表支持新闻查询功能。 相关问: 1. 用户密码应该如何加密存储? 2. 如何设计新闻表以支持高效的新闻查询? 3. 在用户量大的情况下,如何优化用户表的查询性能?</think>### 用户表设计指南(支持新闻查询功能) #### 核心字段设计 ```sql CREATE TABLE users ( user_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户唯一标识符', username VARCHAR(50) NOT NULL UNIQUE COMMENT '登录用户名', password_hash CHAR(60) NOT NULL COMMENT 'BCrypt加密密码', email VARCHAR(100) UNIQUE COMMENT '邮箱(用于找回密码)', display_name VARCHAR(50) COMMENT '显示名称', role ENUM('reader', 'author', 'editor', 'admin') DEFAULT 'reader' COMMENT '用户角色', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间', last_login TIMESTAMP NULL COMMENT '最后登录时间', status ENUM('active', 'suspended') DEFAULT 'active' COMMENT '账户状态' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` #### 关键设计说明 1. **用户标识** - `user_id` 作为主键,用于关联新闻表(如 `news.author_id = users.user_id`) - `username` 唯一索引,支持登录和精确查询 2. **权限控制** - `role` 字段实现权限分级: - `reader`:仅可查看公开新闻 - `author`:可发布/管理自己的新闻 - `editor`:可编辑所有新闻 - `admin`:系统管理权限 - 通过 JOIN 查询实现新闻可见性控制: ```sql SELECT * FROM news JOIN users ON news.author_id = users.user_id WHERE users.status = 'active' AND (news.visibility = 'public' OR users.user_id = :current_user_id) ``` 3. **安全设计** - 密码使用 `BCrypt` 加密存储(60字符固定长度) - 独立 `status` 字段控制账户状态,避免物理删除 - `last_login` 记录用于异常登录检测 4. **查询优化** ```sql -- 创建索引加速查询 CREATE INDEX idx_user_role ON users(role); CREATE INDEX idx_user_status ON users(status); CREATE INDEX idx_login_time ON users(last_login); ``` #### 新闻关联查询示例 ```sql -- 查询某作者发布的活跃新闻 SELECT news.* FROM news JOIN users ON news.author_id = users.user_id WHERE users.username = '科技小编' AND users.status = 'active' AND news.publish_status = 'published'; -- 查询编辑负责的新闻分类 SELECT category, COUNT(*) FROM news JOIN users ON news.editor_id = users.user_id WHERE users.user_id = 1024 GROUP BY category; ``` #### 性能优化建议 1. **数据量较大时(>100万用户)**: - 添加 `created_at` 时间分区 - 读写分离架构 - 热点数据缓存(如使用Redis缓存用户权限) 2. **高频查询优化**: - 使用覆盖索引包含常用字段 - 定期分析慢查询日志 - 对 `role+status` 建立复合索引 3. **扩展性考虑**: ```sql -- 后期可扩展的元数据字段 ALTER TABLE users ADD COLUMN metadata JSON COMMENT '扩展属性'; ``` 存储如:用户偏好分类、通知设置等动态数据 > 参考实践:新闻系统通常采用角色分离设计,普通读者无需邮箱验证即可浏览,但作者/编辑需完成实名认证[^1]。用户表的核心价值在于通过 `user_id` 和 `role` 实现新闻内容与权限的关联控制[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暮棂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值