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

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

  •  1
     
  •   retrocode · 149 天前 · 4317 次点击
    这是一个创建于 149 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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


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

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

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

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

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

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

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

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

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

    都是泪啊😵
    shyangs
        32
    shyangs  
       148 天前
    直接上 ORM 框架. 例如 Hibernate.


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

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