【问题标题】:Questions every good Database/SQL developer should be able to answer [closed]每个优秀的数据库/SQL 开发人员都应该能够回答的问题 [关闭]
【发布时间】:2011-01-08 08:34:49
【问题描述】:

我正在查看Questions every good .Net developer should be able to answer,并对这个问题的内容和方法印象深刻,因此本着同样的精神,我向 Database/SQL Developer 提出这个问题。

您认为优秀的数据库/SQL 程序员应该能够回答哪些问题

【问题讨论】:

    标签: sql database


    【解决方案1】:

    不同类型的 JOIN:

    • 内连接
    • 左外连接和右外连接
    • 完全加入
    • 交叉连接

    查看 Jeff Atwood 的Visual Explanation of JOINs

    • 什么是密钥?候选键?主键?备用钥匙?外键?
    • 什么是索引,它对您的数据库有何帮助?

    • 有哪些可用的数据类型以及何时使用哪些数据类型?

    【讨论】:

    • 如果你不彻底了解联接,你就不能成为一名数据库程序员。这将是第一个问题,如果答案错误,我不会再问其他任何人。
    • 一般理解集合论是成为一名优秀的 sql 开发人员的先决条件。所以我也会在你的列表中添加联合和交叉点。
    • 加入?! Nuthin' 一个很好的非规范化、epic 比例的整体表无法处理......:p
    • 我们不要侮辱集合论者 - 探索联合和交集并不等同于“理解集合论”
    • 在询问不同类型的join时,不要让受访者解释它们,而是提出一组问题,需要受访者使用它们来解决。许多“数据库开发人员”可以解释连接,但不会编写或知道何时应用它们。
    【解决方案2】:

    转载my answer here,作为主题的一般指南。

    基础知识


    1. SELECTing 表中的列
    2. 聚合第 1 部分:COUNTSUMMAX/MIN
    3. 聚合第 2 部分:DISTINCTGROUP BYHAVING

    中级


    1. JOINs,ANSI-89 和 ANSI-92 语法
    2. UNIONUNION ALL
    3. NULL 处理:COALESCE & 原生 NULL 处理
    4. 子查询:INEXISTS 和内联视图
    5. 子查询:相关
    6. WITH 语法:子查询分解/CTE
    7. 观看次数

    高级主题


    • 函数、存储过程、包
    • 透视数据:CASE 和 PIVOT 语法
    • 分层查询
    • 游标:隐式和显式
    • 触发器
    • 动态 SQL
    • 实体化视图
    • 查询优化:索引
    • 查询优化:解释计划
    • 查询优化:分析
    • 数据建模:范式,1 到 3
    • 数据建模:主键和外键
    • 数据建模:表约束
    • 数据建模:链接/推论表
    • 全文检索
    • XML
    • 隔离级别
    • 实体关系图 (ERD),逻辑和物理
    • 事务:COMMITROLLBACK、错误处理

    【讨论】:

    • 就个人而言,我认为有几个“高级”项目应该归入“中级”或“胜任”之下。 “高级”将是非规范化、分区、查询/索引提示、复制、锁定和死锁,以及所有我们希望我们不必处理的疯狂的东西。不过,不错的清单!
    • @Aaronaught:分区和复制更面向 DBA。我有点用隔离级别介绍了锁定。
    • 皮夫。我不相信标签;无论您接受与否,您都是 DBA。 ;)
    • @Aaronaught:如果我有 访问权限,我就是一名 DBA:p
    • 我会把交易作为基本的 - 如果你不知道该怎么做,那么任何保存的数据都不能被信任
    【解决方案3】:

    这里有几个:

    • 什么是标准化,为什么会这样 重要吗?
    • 在哪些情况下,您 会去规范化数据吗?
    • 什么是事务,为什么会这样 重要吗?
    • 什么是参照完整性及其原因 重要吗?
    • 需要采取哪些步骤 调查慢速数据库的报告 性能?

    【讨论】:

      【解决方案4】:

      什么是sql注入,如何预防?

      什么是游标,什么时候使用(或不使用),为什么?

      【讨论】:

        【解决方案5】:

        我放置这个答案是因为 Erwin Smout 发布了一个错误的 answer,它强调了可能需要特别防范它。

        欧文建议:

        “为什么每个 SELECT 都应该包含 DISTINCT ?”

        一个更合适的问题是:如果有人声称:“每个 SELECT 总是包含 DISTINCT”;您如何评论该声明?

        如果候选人无法在火焰中击落索赔,他们要么:

        • 不理解声明的问题。
        • 缺乏批判性思维能力。
        • 缺乏沟通技术问题的能力。

        记录在案

        1. 假设您的查询是正确的,并且不返回任何重复项,那么包含 DISTINCT 只会强制 RDBMS 检查您的结果(零收益,以及大量额外处理)。
        2. 假设您的查询不正确,并且确实返回重复项,那么包含 DISTINCT 只会隐藏问题(再次添加加工)。最好能发现问题并修复您的查询...这样会运行得更快。

        【讨论】:

        • 他们可能读过 C.J.Dates 'Database in depth',默认情况下主张 DISTINCT。 (参见 books.google.com 第 52 页。)
        • 我今天也在想不同的事情...+1
        【解决方案6】:

        在我们公司,我们没有提出很多记忆力好的人都能回答的 SQL 问题,而是创建了一个 SQL Developers 测试。该测试旨在让候选人将具有规范化和 RI 考虑、检查约束等的可靠模式放在一起。然后能够创建一些查询以生成我们正在寻找的结果集。他们根据我们提供给他们的简短设计规范创建所有这些。他们可以在家里这样做,并且可以根据需要(在合理范围内)花费尽可能多的时间。

        【讨论】:

          【解决方案7】:

          我会给出一个写得很糟糕的查询,并询问他们将如何进行性能调整。

          我想问一下集合论。如果不了解集合操作,就无法有效地查询关系数据库。

          我会给他们一些游标示例,并询问他们将如何重写它们以使其基于集合。

          如果工作涉及导入和导出,我会询问有关 SSIS(或其他数据库使用的其他工具)的问题。如果涉及编写报告,我想知道他们了解聚合和分组(以及 Crystal Reports 或 SSRS 或您使用的任何电子报告工具)。

          我会问这三个查询的结果差异:

          select  a.field1
                  , a.field2
                  , b.field3
          from table1 a
          join table2 b
              on a.id = b.id
          where a.field5 = 'test'
              and b.field3 = 1
          
          select  a.field1
                  , a.field2
                  , b.field3
          from table1 a
          left join table2 b
              on a.id = b.id
          where a.field5 = 'test'
              and b.field3 = 1
          
          select  a.field1
                  , a.field2
                  , b.field3
          from table1 a
          left join table2 b
              on a.id = b.id and b.field3 = 1
          where a.field5 = 'test'
          

          【讨论】:

          • 我认罪:后两者有什么区别?我认为它们实际上是相同的。
          • 最后两个会返回不同的结果,前两个会返回相同的结果。在 where 子句中对表 b 设置条件会将其转换为内连接,因为整个结果集必须满足该条件,如果表 b 中没有匹配的记录,则不会满足该条件。 (除非这种情况类似于 b.id 为空。)无法告诉您我必须修复这种代码多少次(事实上,就在今天早上)。
          • 我可以告诉你它们有什么相同之处:它们都有奇怪的逗号位置(我理解其中的原因,但需要一点时间来适应)。
          【解决方案8】:

          和有什么区别 聚集索引和非聚集索引 索引?

          我要问的另一个不针对特定服务器的问题是:

          什么是死锁?

          【讨论】:

          • AFAIK,该术语仅适用于 MySQL 和 SQL Server
          • OMG 是对的。这是特定于数据库的。其他数据库具有相同的功能。 Oracle 具有与聚集索引相同的索引组织表。不仅如此,聚集索引和包含表中每一列的非聚集索引几乎没有区别。我认为,这个问题的真正意义在于看这个人是否知道索引类型的不同物理存储特性。
          • 其他厂商叫什么?
          • @OMG - AFAIK 聚集索引起源于 Sybase,MSSQL 的一个版本直到(至少)6.5,之后 MS 几乎重新编码了整个事情;他们全面的更好的努力之一。从表面上看,Sybase ASE 的外观和感觉仍然很像 6.5。
          • 琐事:索引的整个概念,包括语法和术语,都没有在 SQL 标准中指定!这是一个实现细节。令人惊讶的是,供应商之间的相似之处与现有的一样多。
          【解决方案9】:

          知道不使用,为什么不使用:

          SELECT *
          

          【讨论】:

          • 我经常这样做。它节省了打字,而且我不必记住列名。这有什么问题?
          • @gary: 返回不必要数据的风险,隐藏列名更改错误...
          • @gary,不应在生产代码中使用,因为如果底层数据结构发生更改,它将破坏您的查询。话虽如此,我不时会像下一个开发人员一样感到内疚 - 但只有当我知道系统在我的完全控制之下时
          • @gary:如果您有 text/blob 列并返回多行,您将对系统造成不必要的压力。
          • 咳咳……除非您维护包括每一列在内的大量索引,否则SELECT * 将阻止使用覆盖索引的高效索引操作?这是最重要的原因!
          【解决方案10】:

          一个有趣的问题将涉及relational division,或者如何表达“for all”关系,这需要嵌套not exists 子句。

          问题来自this link

          给定下表,代表可以驾驶飞机和机库中飞机的飞行员:

          create table PilotSkills (
            pilot_name char(15) not null,
            plane_name char(15) not null
          )
          
          create table Hangar (
            plane_name char(15) not null
          )
          

          选择可以驾驶机库中每架飞机的飞行员的名字。

          答案:

          select distinct pilot_name
          from PilotSkills as ps1 
          where not exists (
            select * from hangar
            where not exists (
              select * from PilotSkills as ps2 where 
                ps1.pilot_name = ps2.pilot_name and 
                ps2.plane_name = hangar.plane_name
            )
          )
          

          或者……

          选择所有已接受带有10 most popular programming languages 标记的问题的答案的堆栈溢出用户。

          (可能的)答案(假设有一个Accepted_Answers 视图和一个带有所需标签的Target_Language_Tags 表):

          select distinct u.user_name
          from Users as u
          join Accepted_Answers as a1 on u.user_id = a1.user_id
          where not exists (
            select * from Target_Language_Tags t
            where not exists (
              select * 
                from Accepted_Answers as a2
                join Questions as q on a2.question_id = q.question_id
                join Question_Tags as qt on qt.question_id = q.question_id 
              where 
                qt.tag_name = t.tag_name and
                a1.user_id = a2.user_id
            )
          )
          

          【讨论】:

          • 这无疑是一个有趣的问题。但是,我怀疑是否有很多公司需要他们的开发人员每天处理此类情况。
          • 很公平,但我认为回答这个问题显示了大量的逻辑推理,这对于优秀的数据库开发人员来说是必不可少的。
          【解决方案11】:

          当我们有一个复杂的应用程序使用经过适当优化的 ORM 并实现缓存系统(例如 memcached)时,为什么要雇用您?

          这是一个严肃的问题,他们应该能够证明自己的存在。正如 Jeff Atwood 喜欢说的“Hardware is Cheap, Programmers are Expensive

          【讨论】:

          • ORMoptimized 是矛盾的。 ORM 使开发更高效,而不是运行时性能。使用 memcache 也不错,但您仍然需要有人分析哪些数据最适合存储在缓存层中。
          • @Bill 所以所有的休眠分析、急切/延迟加载、批量获取,都不是优化?虽然让某人对数据进行统计以查看什么使缓存得到最佳利用是件好事,但这难道不是更多的 DBA 工作而不是 SQL 开发人员吗?哎呀,我不明白为什么开发人员不能在优化过程中自己这样做。
          • @jcm:不,它们不是优化。您提到的那些功能是补偿使用 ORM 造成的低效率。如果您不使用 ORM,则需要它们。 :-)
          • 但是开发时间甚至比不上低效代码给业务带来的额外成本。如果我因为低效的代码每天花费 1,000 名用户 5 分钟,那么对于企业来说,实际上花费额外的两分钟来编写高效的代码难道不值得吗?坦率地说,当开发人员实际上是 SQL 专家时,我看不出 ORM 在哪里可以节省那么多时间。
          • @HLGEM:事实上,大多数企业似乎宁愿缩短产品上市时间,即使这意味着他们编写的代码很糟糕。他们可能认为他们以后总会有机会解决痛点。我不支持这种做法,只是观察到它很常见。 :-)
          【解决方案12】:

          比较和对比 sql/rdbms 解决方案和 nosql 解决方案之间的差异。在不了解与竞争对手相比的优势和劣势的情况下,您不能声称自己是任何技术的专家。

          【讨论】:

            【解决方案13】:

            举一个去规范化更可取的例子。

            (我喜欢这个,因为人们从大学毕业后就想把所有东西都变成第三范式)

            【讨论】:

            • “日志文件”是一个很好的答案。您可能希望记录更改数据库状态的操作,但如果将日志表链接到其他表,则操作的真实原始上下文可能会丢失。甚至不要提及级联删除......
            • 日志文件是否应该在数据库中? 先生,我质疑你的问题!
            • @jeff 你实际上是在质疑我的回答!我并没有说这是一个精心设计的答案,只是一个好的答案。放过我吧!
            • 当快速获取复杂数据的重要性大于清理数据完整性的数据库的成本时,非规范化更可取。
            • @Jeff 听说过 Sarbanes Oxley 吗? :) 这样做还有其他原因,但您的问题的答案是,“有时,但只有当您别无选择时”。
            【解决方案14】:
            • 作为开发人员,哪些数据库类型给您带来了更多的理解和调试麻烦? 预期的答案,恕我直言,使用不同日期/时间戳类型和 BLOB 遇到问题的经验

            • 什么时候使用位图索引比较方便?

            【讨论】:

              【解决方案15】:

              explain plan 做什么以及如何解释您从中获得的结果。

              【讨论】:

                【解决方案16】:
                • 如何检测和解决应用层的并发问题?
                • 通常可用的锁定范例有哪些,并讨论它们的优缺点。
                • 讨论 NULL 值和相关问题。
                • 就#表、#行、#用户而言,您使用过的最大数据库系统是什么。

                还有以下特定于平台(SQL Server)的问题:

                • 讨论 IDENTITY 列。
                • 时间戳数据类型用于什么?

                【讨论】:

                  【解决方案17】:

                  该应用程序每天 24 小时都在使用。您的维护/更新窗口是每月 2 小时,您打算如何最大限度地减少中断?

                  【讨论】:

                    【解决方案18】:

                    这里几乎提到了所有内容。我想分享一个数据库高级经理问我的问题。我发现这个问题很有趣,如果你深入思考它,它就会有很多意义。

                    问题是 - 你会如何向你 5 岁的孩子描述数据库?

                    【讨论】:

                      【解决方案19】:
                      • 解释两者之间的区别 内连接和外连接。
                      • 什么是笛卡尔积?
                      • 解释第三范式

                      【讨论】:

                        【解决方案20】:
                        • 解释对表的可能限制
                        • 解释视图(并具体化)
                        • 解释序列
                        • 解释触发器

                        【讨论】:

                          【解决方案21】:
                          • 使用 adhoc/on-the-fly SQL 语句有什么缺点,您会怎么做?

                          该区域会对数据库的性能和安全性产生巨大影响。搞错了,你可能会陷入痛苦的世界。

                          • 在什么情况下会使用 adhoc/on-the-fly SQL 语句?

                          因为规则总是有例外:)

                          【讨论】:

                            【解决方案22】:

                            “为什么每个 SELECT 都应该包含 DISTINCT ?”

                            【讨论】:

                            • 我不明白你的意思。你能扩展一下你的意思吗?
                            • 除非我的目的是检查我是否会挑战那个垃圾声明;如果有人认真地问我这个问题,我会告诉他们我不再对这份工作感兴趣。
                            • 好吧,看来斯穆特先生是认真的。 :/ 在您造成更多损害之前,请注意:您的主张是错误,实际上相反更正确! 1)假设您的查询是正确的,并且不返回任何重复项,那么包括 DISTINCT 只会强制 RDBMS 检查您的结果(零收益,以及大量额外处理)。 2) 假设您的查询不正确,并且 确实 返回重复项,则包括 DISTINCT 只是 *隐藏 问题(再次进行额外处理)。发现问题并修复您的查询会更好......这样会运行得更快。
                            猜你喜欢
                            • 2010-09-26
                            • 2011-10-05
                            • 1970-01-01
                            • 2010-09-08
                            • 2010-11-09
                            • 2010-10-03
                            • 1970-01-01
                            • 1970-01-01
                            • 2010-10-17
                            相关资源
                            最近更新 更多