例如从数据库中查询一个有效的账户信息
select * from user_account where user_id = 1 and is_delete = 0
select * from user_account where user_id = 1
if (userAccount.getIsDelete() != 0) {
log.error("用户信息已经删除");
return;
}
求解...
1
hlwjia 2019-06-17 23:52:48 +08:00 via Android
去问产品经理,看他具体要什么需求。
是要明确告诉一个已经被删了的用户他的账号已经被删了?那只能代表没删干净。 如果要表现地好像删干净了,应该是显示找不到这个用户。 |
3
zjp 2019-06-18 00:05:15 +08:00
索引? is_delete 这种枚举字段不会有索引吧,而且应用层做数据过滤不会比数据库快
|
4
sakudie OP @zjp 是的,只有 idx_user_id 这个索引。但是我搞不清楚 额外的 is_delete = 0 过滤会不会影响到索引使用。。
|
5
leishi1313 2019-06-18 00:30:16 +08:00 via Android
你查两个字段肯定比一个字段要慢,但是这都比在代码里用 for 来过滤要快,尽量把能放 sql 的都放 sql 里
|
6
moult 2019-06-18 00:34:47 +08:00 via iPhone
@sakudie 你这个情况的话,user id 一般是主键,有主键在的查询,肯定直接用主键索引了,就算其他查询条件有索引一般都不会去用的。
|
7
misaka19000 2019-06-18 00:35:12 +08:00
肯定放在 SQL 里面,不然你会多查出来很多无用的数据
|
8
akira 2019-06-18 00:44:01 +08:00
@sakudie 一般情况下不影响到索引。
不一般的情况呢,例如你们有一百万个账户信息,里面有 50 万个的电话号码是一样的,然后你是基于电话号码来查询,这种情况下就会出问题了。而且这种情况下,用代码来处理,效率会更差 |
9
wenzhoou 2019-06-18 07:57:27 +08:00 via Android
你的这种情况。用户 ID 是唯一的吗。当一个用户被删除了以后还可以创建同名用户吗?
如果不可以,那么就不可以表现的删干净了的样子。否则会导致人家死活创建不了用户,还不知道为什么。 假如可以。那新创建用户是不是一进去就继承了老用户的数据,怎么隔离? 这是其一。 其二,用户 ID 有索引,基本上查询是只读取索引区,根据索引区找到对应数据的地址,然后找到数据,接下来处理其他的非索引条件,SQL 预处理会这样干的。这样已经很快了。因为根据索引,你这里能找的数据量很小,可能就一两条数据,所以加不加删除判断对 SQL 文的快慢基本没有影响! 综上,你主要要看业务。业务逻辑必须自洽。 |
10
ragnaroks 2019-06-18 08:33:54 +08:00
放在 SQL 里,但不要无脑把逻辑都放在 SQL 里,能不放就不放
|
11
ragnaroks 2019-06-18 08:36:50 +08:00
之前遇到和你类似的需求,`user`有个 Blocked,用于判断用户是否因为开挂 /辱骂等原因被封禁但不删除.
最开始是放 SQL 里,300w 条数据里面插了差不多 10ms,非常慢了,后来直接按 Id 拉取这条记录用业务代码去判断,<1ms 看你的代码应该用的是 java,你这个需求还是先放 SQL 里面吧 |
12
MrSheng 2019-06-18 09:09:40 +08:00
如果 is_delete 没有其他业务逻辑,仅用来表示“已删除的数据”,那么应该放在 SQL 中,这条数据对应用来说是透明的,任何时候都不要查出来。当结果返回空的时候,就跟没有这条数据一样,仍然可以插入新数据而不受原始数据影响。
如果 is_delete 还有其他业务逻辑,那么就不应该放在 SQL 中,而且后面很(百)可(分)能(百)会复用此字段。 |
13
skiy 2019-06-18 09:30:16 +08:00
看需求吧。
|
14
telami 2019-06-18 09:46:17 +08:00 1
你这 user_id 都是主键索引了,查找的范围大大缩小了,基本上都能定位到一条数据了,加上 is_delete 根本不影响。
自己可以 [explain] 一下,看看索引使用情况,这玩意都是有迹可循的,哪有什么不清楚的 |