V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
retrocode
V2EX  ›  问与答

你们对禁止使用 SELECT *有什么看法?我被恶心到了...

  •  1
     
  •   retrocode · 2021-12-28 17:49:46 +08:00 · 5215 次点击
    这是一个创建于 1052 天前的主题,其中的信息可能已经有所发展或是发生改变。

    七八年的老项目,一个表几十个字段,随便一条 SQL 又臭又长,二十几行的 SQL 有十行都是各种字段,然后各种嵌套看的我眼睛都快瞎了

    关键还是在 JAVA 中用字符串拼接然后到处复制粘贴,这改一个字段那改一个字段这种,真正贯彻了没有一个多余字段这种概念.

    用*换取来的那点性能真的值得做到这种地步吗....

    33 条回复    2021-12-29 20:23:40 +08:00
    clf
        1
    clf  
       2021-12-28 17:51:39 +08:00
    一般我们都是用 ORM 框架自动转换的……

    还有就是写 SQL 的时候用 navicat 里的查询编辑器会自动生成全部字段的。所以……
    kop1989
        2
    kop1989  
       2021-12-28 17:53:07 +08:00
    这就属于 DAO 在实现的时候,没有充分贯彻单一职责原则。
    不用*是对的,但没有按需取字段,就是白忙活。
    retrocode
        3
    retrocode  
    OP
       2021-12-28 17:59:52 +08:00
    @clf #1 讲真我看那代码就觉得像是先写的 sql 然后直接粘贴进项目的,然后 java 自动截段换行.阅读起来太痛苦了,非在这个项目上干了 2 年的老哥驾驭不了


    @kop1989 #2 他们就是按需取字段把我恶心到了, 一个 file_path 都专门写个 if 判断下在加
    potatowish
        4
    potatowish  
       2021-12-28 18:09:55 +08:00 via iPhone
    一个表几十个上百个字段,select*性能是会有点影响的,把需要的字段列出来维护又比较麻烦,这时候就可以考虑水平拆分,在单一职责原则下,减少单个表的字段数量,然后再使用 select*,字段减少了,对性能影响可以忽略不计
    clf
        5
    clf  
       2021-12-28 18:22:20 +08:00
    @retrocode #3 其实正常。我还遇到过大部分都是调存储过程的,得去写存储过程。然后存储过程里的 SQL 更加狂野。基本靠老带新才能接手。
    gearkey
        6
    gearkey  
       2021-12-28 18:26:39 +08:00 via Android
    这。。表设计得不大好吧,如果是比较大的项目,分行写的基础上也把字段分类整理一下,最好加点注释,就优美了
    melkor
        7
    melkor  
       2021-12-28 18:41:33 +08:00 via iPhone   ❤️ 1
    这些字段什么情况要用哪些,应该定义出语义化的接口,这样就不用*了
    retrocode
        8
    retrocode  
    OP
       2021-12-28 18:54:10 +08:00   ❤️ 1
    @clf #5 这么狂野的我 19 年做过,是个仓储项目,当时负责 DBA 的老哥跟我炫耀他们系统一个表 200 个字段后台只需按需启用接口,最后我们只需要调用 SP 即可.

    整个项目全是存储过程,业务逻辑全在 SQL 里,看着就头大.

    幸运的是当时我只做前端不用碰 SQL...
    Goooooos
        9
    Goooooos  
       2021-12-28 19:03:07 +08:00
    @retrocode #8 之前有人问为什么不用存储过程来写逻辑
    wanguorui123
        10
    wanguorui123  
       2021-12-28 22:32:36 +08:00
    一个表字段过多就不太合理
    zzzain46
        11
    zzzain46  
       2021-12-28 22:41:45 +08:00 via iPhone
    @clf 老哥请问 navicat 这个自动生成怎么操作的,求指教
    lovedoing
        12
    lovedoing  
       2021-12-28 23:41:03 +08:00
    禁用 select *是 SQL 规范的基本原则
    chihiro2014
        13
    chihiro2014  
       2021-12-29 00:31:46 +08:00
    JPA 的 projection 就可以按需取字段,非常方便
    lululau
        14
    lululau  
       2021-12-29 00:38:06 +08:00
    active record 框架它不香吗,我就一直很好奇像 MyBatis 这种开发体验几乎和写原始 SQL 一样的框架,怎么就成为中国 Java 开发的事实标准了的
    h82258652
        15
    h82258652  
       2021-12-29 09:01:18 +08:00
    写个鸡儿 sql ,orm 香爆了
    我公司前几天才发生过数据库表字段名字改了,代码里有 sql 漏改的情况
    RedBeanIce
        16
    RedBeanIce  
       2021-12-29 09:05:25 +08:00 via iPhone
    xml 与 resultmap
    weixiangzhe
        17
    weixiangzhe  
       2021-12-29 09:10:07 +08:00 via iPhone
    我觉得不用*还比较安全, 保不齐哪天加了个私密的字段就一并带上去了
    dddd1919
        18
    dddd1919  
       2021-12-29 09:15:12 +08:00
    @lululau 设计不行,只能靠这种半 ORM 来实现一些 ORM 无法满足的需求,比如疯狂 join
    ferock
        19
    ferock  
       2021-12-29 09:35:30 +08:00 via iPhone
    论框架中 sql map 的重要性
    onhao
        20
    onhao  
       2021-12-29 09:48:32 +08:00
    单条数据的获取 * 无任何问题, 但是多行数据的获取就要慎重用 *了
    这是使用 mysql 趟过的一些坑。https://wuhao.pw/category/mysql/
    chanchan
        21
    chanchan  
       2021-12-29 09:51:28 +08:00
    @lululau 确实,太原始了,虽然刚入行写了一段时间,个人还是更喜欢 JPA hibernate
    moyi97
        22
    moyi97  
       2021-12-29 10:25:20 +08:00
    对于现在的数据仓库来说,很多数据开发(大部分用 sql) 中的规范中,是坚决禁止 select * 的.但是对于代码中拼 sql 这种行为我觉得很难看(虽然说我也干过.)
    arthas2234
        23
    arthas2234  
       2021-12-29 10:55:45 +08:00
    最讨厌的就是在代码里面写 sql ,贼难维护
    bing1178
        24
    bing1178  
       2021-12-29 11:05:59 +08:00
    那 select * 有啥问题吗?
    bing1178
        25
    bing1178  
       2021-12-29 11:07:45 +08:00
    那 select * 有啥问题吗?
    如果 70%字段我都需要 就是 *
    如果 只有 10%字段需要 再上量大 我会 写上字段

    这样没啥问题吧?
    clf
        26
    clf  
       2021-12-29 12:02:54 +08:00
    @zzzain46 #11 navicat 创建一个查询后有可视化的 SQL 编辑器,直接选择你要的数据表和勾选要的字段就行。会自动帮你写好 join 等 SQL 语法。
    ppphp
        27
    ppphp  
       2021-12-29 12:40:25 +08:00
    select *和 anyscript 一样,属于语言方便给程序员写脚本而不是生产环境实际跑起来的代码
    FrankAdler
        28
    FrankAdler  
       2021-12-29 13:07:40 +08:00
    一个表,到处都在使用,分散在项目的各个地方,这是代码分层的问题,不然就算不使用 select * 就算单表字段很多,也不应该这么改死人
    atpking
        29
    atpking  
       2021-12-29 14:34:08 +08:00
    写多年的 rails 已经习惯 active_record 解决战斗了, 都要退化到只会 join 了
    Citrus
        30
    Citrus  
       2021-12-29 14:42:18 +08:00
    @bing1178

    跟字段数量什么的都无关。
    SELECT * 最主要的问题是会引入非预期的字段。最典型的是,你的 Java 程序使用 MyBatis 或者直接 JDBC 调用,然后我在数据库里新增了一个字段。于是你在解析 SELETE * 的结果时候,由于返回参数数量不匹配,直接失败。

    当然,并不是所有写法都会有这个问题,但是大多数常用的方式都存在这个隐患,所以阿里才会把不要用 SELETE * 写入代码规范。

    [强制] 在表查询中,一律不要使用 * 作为查询的字段列表,需要哪些字段必须明确写明。
    说明:1 )增加查询分析器解析成本。2 )增减字段容易与 resultMap 配置不一致。3 )无用字段增加网络
    消耗,尤其是 text 类型的字段。
    retrocode
        31
    retrocode  
    OP
       2021-12-29 15:16:05 +08:00 via Android
    @lululau 设计和业务问题,国内传统企业都是跟业务走,这种公司里程序员甚至架构师产品经理的地位都不高,今天改个需求明天废弃字段还催工期,然后对代码质量要求不高功能实现就 ok ,日积月累初始架构设计的再好也迟早得崩要么毁灭要么变屎山。

    比如新需求 username 字段废弃,原有系统中的 username 改为 xxx 表中的 new_username 字段,而且早上提需求,中午问进度,第二天早上要上线。

    现在改前后端根本来不及,还会有浏览器缓存,cdn 等问题,这种狂野的需求,最简单的方法是修改 sql 字段 new_username AS username 。

    都是泪啊😵
    shyangs
        32
    shyangs  
       2021-12-29 15:55:50 +08:00
    直接上 ORM 框架. 例如 Hibernate.


    MyBatis 這種半吊子的,只能算 SQL 模板引擎.

    XML 沒有 Java 語法級別的提示和靜態語言重構輔助.
    新增字段? 就搜一下關鍵字然後一行一行改 XML 吧,一不小心就改錯了或者漏了(我相信任何用過 MyBatis 的人都遇到過這個問題)
    qfdk
        33
    qfdk  
       2021-12-29 20:23:40 +08:00 via iPhone
    那天用了* 被老大说了….. 因为这样会导致有过多的信息查询出来 导致 数据臃肿. 简单来说就是用什么拿什么
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3639 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 05:03 · PVG 13:03 · LAX 21:03 · JFK 00:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.