V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
sakudie
V2EX  ›  数据库

数据查询 is_delete = 0 放在 sql 里 还是查询后代码判断

  •  
  •   sakudie · 2019-06-17 23:47:05 +08:00 · 2350 次点击
    这是一个创建于 1774 天前的主题,其中的信息可能已经有所发展或是发生改变。

    例如从数据库中查询一个有效的账户信息

    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;
    }
    

    求解...

    14 条回复    2019-06-18 09:46:17 +08:00
    hlwjia
        1
    hlwjia  
       2019-06-17 23:52:48 +08:00 via Android
    去问产品经理,看他具体要什么需求。

    是要明确告诉一个已经被删了的用户他的账号已经被删了?那只能代表没删干净。

    如果要表现地好像删干净了,应该是显示找不到这个用户。
    sakudie
        2
    sakudie  
    OP
       2019-06-17 23:56:38 +08:00
    @hlwjia 主要是对数据库的索引使用有点不明白,不确定两种方式对索引的使用有何区别,是否存在效率上的区别
    zjp
        3
    zjp  
       2019-06-18 00:05:15 +08:00
    索引? is_delete 这种枚举字段不会有索引吧,而且应用层做数据过滤不会比数据库快
    sakudie
        4
    sakudie  
    OP
       2019-06-18 00:14:59 +08:00
    @zjp 是的,只有 idx_user_id 这个索引。但是我搞不清楚 额外的 is_delete = 0 过滤会不会影响到索引使用。。
    leishi1313
        5
    leishi1313  
       2019-06-18 00:30:16 +08:00 via Android
    你查两个字段肯定比一个字段要慢,但是这都比在代码里用 for 来过滤要快,尽量把能放 sql 的都放 sql 里
    moult
        6
    moult  
       2019-06-18 00:34:47 +08:00 via iPhone
    @sakudie 你这个情况的话,user id 一般是主键,有主键在的查询,肯定直接用主键索引了,就算其他查询条件有索引一般都不会去用的。
    misaka19000
        7
    misaka19000  
       2019-06-18 00:35:12 +08:00
    肯定放在 SQL 里面,不然你会多查出来很多无用的数据
    akira
        8
    akira  
       2019-06-18 00:44:01 +08:00
    @sakudie 一般情况下不影响到索引。

    不一般的情况呢,例如你们有一百万个账户信息,里面有 50 万个的电话号码是一样的,然后你是基于电话号码来查询,这种情况下就会出问题了。而且这种情况下,用代码来处理,效率会更差
    wenzhoou
        9
    wenzhoou  
       2019-06-18 07:57:27 +08:00 via Android
    你的这种情况。用户 ID 是唯一的吗。当一个用户被删除了以后还可以创建同名用户吗?
    如果不可以,那么就不可以表现的删干净了的样子。否则会导致人家死活创建不了用户,还不知道为什么。
    假如可以。那新创建用户是不是一进去就继承了老用户的数据,怎么隔离?
    这是其一。

    其二,用户 ID 有索引,基本上查询是只读取索引区,根据索引区找到对应数据的地址,然后找到数据,接下来处理其他的非索引条件,SQL 预处理会这样干的。这样已经很快了。因为根据索引,你这里能找的数据量很小,可能就一两条数据,所以加不加删除判断对 SQL 文的快慢基本没有影响!

    综上,你主要要看业务。业务逻辑必须自洽。
    ragnaroks
        10
    ragnaroks  
       2019-06-18 08:33:54 +08:00
    放在 SQL 里,但不要无脑把逻辑都放在 SQL 里,能不放就不放
    ragnaroks
        11
    ragnaroks  
       2019-06-18 08:36:50 +08:00
    之前遇到和你类似的需求,`user`有个 Blocked,用于判断用户是否因为开挂 /辱骂等原因被封禁但不删除.
    最开始是放 SQL 里,300w 条数据里面插了差不多 10ms,非常慢了,后来直接按 Id 拉取这条记录用业务代码去判断,<1ms

    看你的代码应该用的是 java,你这个需求还是先放 SQL 里面吧
    MrSheng
        12
    MrSheng  
       2019-06-18 09:09:40 +08:00
    如果 is_delete 没有其他业务逻辑,仅用来表示“已删除的数据”,那么应该放在 SQL 中,这条数据对应用来说是透明的,任何时候都不要查出来。当结果返回空的时候,就跟没有这条数据一样,仍然可以插入新数据而不受原始数据影响。

    如果 is_delete 还有其他业务逻辑,那么就不应该放在 SQL 中,而且后面很(百)可(分)能(百)会复用此字段。
    skiy
        13
    skiy  
       2019-06-18 09:30:16 +08:00
    看需求吧。
    telami
        14
    telami  
       2019-06-18 09:46:17 +08:00   ❤️ 1
    你这 user_id 都是主键索引了,查找的范围大大缩小了,基本上都能定位到一条数据了,加上 is_delete 根本不影响。

    自己可以 [explain] 一下,看看索引使用情况,这玩意都是有迹可循的,哪有什么不清楚的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4506 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 36ms · UTC 01:07 · PVG 09:07 · LAX 18:07 · JFK 21:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.