用SQL思考问题

2021-04-10 05:29:07

SQL是不同的。 SQL是一种语言,我可以询问电脑一个问题,它将弄清楚如何为我回答它。

SQL的流利是一个非常实用的技能。这将使您的生活更轻松地日复一日。它并不完美,它有许多缺陷(如null),但它是广泛的用途(不同,说,prolog或d)。

作为工程师,SQL数据库通常会保存我编写大量代码来转换数据。他们拯救我担心管理像内存一样的有限资源的最佳方式。我写下问题,数据库(通常)鉴于现在数据的形状,以及可用于处理它的资源,以备注使用最有效的算法。喜欢魔法。

SQL帮助我以不同的方式考虑数据,让我专注于我想问到数据的问题;独立于存储和结构数据的最佳方法。

我最喜欢的Postgres之一能够分别考虑读/写模型。 1)懒洋洋地将数据丢弃为JSON。 2)使用[物质化]视图构建读取模型3)重构在下面的写模型获取SQL的便利性(3)pic.twitter.com/31xhuek7

- Benji Weber(@benjieber)2021年3月20日

作为经理,我经常想衡量事情,了解问题的答案。 SQL让我直接向计算机提出很多问题而无需打扰人。我可以用较短的反馈循环探索我的想法,而不是我只能对我的团队带来问题。

SQL是一种语言,可以以机器可以帮助回答它们的方式表达我们的问题; 在这么多环境中有用。 如果更多的事情讲SQL,那将是盛大的。 想象一下,您可以在壳牌中提出问题,而不是必须教授如何转换数据 SQL非常棒。 那么为什么有很多努力消除了避免它? 我们在其上学习ORM抽象。 我们将SQL数据库视为Gloozed数据库:Chuck数据,拉动数据。 在应用程序代码中转换数据给出了对过程的安慰的控制量,但通常更难且比询问数据库的正确问题。 您是否将SQL视为用于存储和检索数据的语言,或者作为表达问题的语言? 数据库通常可以弄清楚最优于您的问题的最佳方式。 这是两个与1属性的简单关系。 a和b。 每个关系中的单个元组。

创建表A(ID);创建表B(ID int);插入值(1);插入B值(1);从自然加入B中解释分析*;

创建表A(ID int);创建表B(ID int);插入值(1);插入B值(1);解释自然加入B的分析选择*;

“解释分析”告诉我们Postgres如何回答我们的问题。它需要的操作,以及它们有多昂贵。我们还没有告诉它使用Quicksort,它选择这样做。

查看数据库如何做事是有趣的,但让我们通过改变数据来使其更有趣。让我们添加更多值并重新运行相同的查询。

从Generate_series插入SELECT *(1,10000000);从自然加入B中解释分析*;

从Generate_series(1,10000000)中插入SELECT *;解释分析SELECT *从自然加入B中选择*;

我们已经使用generate_series生成有关“A”的一百万元组。注意“排序方法”已更改为使用磁盘,因为与数据库可用的资源相比,数据集更大。我没有告诉它这样做。我刚刚询问了同样的问题,它已经想象出了它需要使用不同的方法来回答问题,现在数据已经改变了。

但实际上我们通过在插入数据后立即运行查询来完成数据库A isservice。尚未有机会赶上。让我们通过在我们的关系中运行分析来强制更新其数据的形状来提供机会。

现在重新运行相同的查询速度较快,而且该方法显着改变。它现在正在使用哈希加入而不是合并连接。它还向查询执行计划引入了并行性。这是一个更快的数量级。再次我不得不告诉数据库来做这一点,它已经弄清楚了一个更容易回答问题的方式,现在它对数据知识了解。

让我们来看看一些构建块SQL给我们表达的问题。我们拥有的最简单的构建块是要求文字价值观。

如果我们想问一下多个斯塔克斯的问题,怎么办:伊德德或城堡或麸皮?这就是联盟进来的地方。

选择'埃德德德'作为ForeName Union选择' CATLYN'作为前缀联盟选择'麸皮'作为foreName除了选择'埃德德德'作为前奏;

选择'埃德德德'作为ForeName Union选择' CATLYN'作为前缀联盟选择'麸皮'作为foreName除了选择'埃德德德'作为前奏;

那些加入家庭的人呢?我们如何在两个家庭中看到谁。这就是交叉进入的地方。

(选择' jamie'作为foreName Union选择' cersei'作为forename Union选择' sansa'作为foreName)交叉(选择' sansa'作为foreName );

(选择' jamie'作为foreName Union选择' cersei'作为forename Union选择' sansa'作为foreName)交叉(选择' sansa'作为foreName );

必须在每次查询中键入每个值都令人繁琐。

SQL使用隐喻“表”。我们有数据表。对我来说,它提供了电子表格的内涵。 Postgres使用我认为更有用的术语“关系”。每个“关系”是一系列数据,其彼此有一些关系。谓词是真实的数据。

创建表鲜明为Select' Sansa'作为ForeName Union选择'埃德德德'作为ForeName Union选择' CATLYN'作为前缀联盟选择'麸皮'作为前奏;创建表Lannister作为选择'杰米'作为ForeName Union选择' Cersei'作为ForeName Union选择' Sansa'作为前奏;

创建表鲜明为Select' Sansa'作为ForeName Union选择'埃德德德'作为ForeName Union选择' CATLYN'作为前缀联盟选择'麸皮'作为forename;创建表纳金斯特作为选择' jamie'作为ForeName Union选择' Cersei'作为ForeName Union选择' Sansa'作为前奏;

现在我们已经存储了我们可以提出的问题的相关数据关系。我们已经存储了“属于房子的成员”和“是房屋纳尼斯特的成员”的事实是真实的。如果我们想要在两个房子里的人。关系和。这是自然加入的地方。

自然连接与基于集和(上面的相交)并不完全相同。即使我们正在比较的两个关系中存在不同的ARINITY元组,自然加入也会起作用。

创建表宠物作为选择'梵文萨萨'作为前夕,'夫人'作为宠物联盟选择'麸皮'作为forename,'夏天'作为宠物;

创建表宠物作为选择'梵文萨萨'作为前夕,'夫人'作为Petunion选择'麸皮'作为forename,'夏天'作为宠物;

现在我们有一个,呢或?我们有一个或以上(Union)。我认为最接近的关系或是一个完整的外部连接。

创建表动物作为选择'女士'作为foreaname,'狼'作为物种联盟选择'夏天'作为foreaname,'狼'作为物种;使用(FORENAME)从STARK全连接动物中选择*;

创建表动物作为选择'女士'作为foreaname,'狼'作为物种联盟选择'夏天'作为foreaname,'狼'作为物种;选择*来自STARK Full外连接动物使用(FORENAME);

好的,所以我们可以用和ors询问简单的问题。还有大多数关系代数的等同物。

呢?更有趣的问题是什么?我们也可以做到这一点。让我们前进一下。

如果我们想要计划对国王登陆的攻击,并且需要考虑我们可以接受的路线。从一些关于地点之间旅行选项的事实开始,让我们询问数据库弄清楚我们的路线。

创建表移动(放置文本,方法文本,纽普兰文本);插入移动(地点,方法,纽墙)值(' winterfell'和#39;马','城堡黑色'),(' winterfell' ,'马','白色港口'),(' winterfell''马','护城河cailin') ,('白色港口和#39;'船'' king'' s登陆'),(' moat cailin' ,'马',' Crossroads Inn'),(' Crossroads Inn''马','''''& #39; LALDING');

创建表移动(放置文本,方法文本,纽普兰文本);插入移动(地方,方法,纽局)值(' winterfell''马','城堡黑色#39;),(' winterfell''马'白色港口和#39;),(' winterfell','''马& #39;,' Moat Cailin'),('白色港口和#39;'船','' s landing' 39;),(' Moat Cailin','马',' Crossroads Inn'),(' Crossroads Inn','马',' king'' lavening');

现在让我们弄清楚一个查询,让我们在目前和目的地之间的计划路线如下

我们不需要存储任何中间数据,我们可以一体地提出问题。这里“Route_Planner”是一个视图(已保存的问题)

创建视图Route_Planner,如递归路由(Place,NewPlace,方法,长度,路径)一样(选择Place,NewPlace,方法,1为长度,从MoveSstarting Point Union(或)或选择 - 下一步旅程路线.Place,移动。圈,移动.Method,路线.Length + 1, - 发现路径路径的额外步骤||' - [' ||路线。&#39 ;] - > ||||移动.Place作为路径 - 描述路线上的移动加入路由的路线.NewPlace =移动.Place - 仅限于现有路线的可达目的地)选择作为起源,纽普兰地点作为目的地,长度,路径|| ' - [' ||方法|| '] - >' ||纽普拉斯罗出来的指示;

创建查看Route_Planner Aswith递归路由(Place,NewPlace,方法,长度,路径)(选择Place,NewPlace,方法,1为长度,从Move-Starting Point Unitl或Select - 或选择 - 下一步route.place,move.newplace,move.method,Route.length + 1, - 发现路径路径上的额外步骤||' - [' || Route.method ||' ] - >' || move.place作为路径 - 描述从route.newplace = move.place - 仅限于现有路线的可达目的地的路径从Move Join路径中描述的路由)选择作为起源,纽普拉斯州的距离仅可达目的地)目的地,长度,路径|| ' - [' ||方法|| '] - >' ||纽普拉斯罗出来的指示;

与我们上面所做的事情相比,我知道这有点“猫头鹰”。我希望它至少说明了什么是可能的。 (这是基于Prolog教程)。我们已经开始了一些关于邻近地点的一些事实,并要求数据库弄清楚我们的路线。

这会保存具有名称给定查询的结果的关系。我们以上做到了

创建表Lannister作为选择'杰米'作为ForeName Union选择' Cersei'作为ForeName Union选择' Sansa'作为前奏;

创建表Lannister作为选择'杰米'作为ForeName Union选择' Cersei'作为ForeName Union选择' Sansa'作为前奏;

创建表将存储静态数据集,每次询问静态数据集时,视图将重新执行查询。即使潜在的事实发生变化,它始终是新鲜的。

这将创建查询的命名部分,称为“公共表表达式”。您可以认为它就像提取方法重构一样。我们为您提供了一部分的疑问,以便更容易理解。这也允许我们使其递归,因此我们可以在部分答案之上构建答案,以便建立我们的路线。

这为我们提供了我们旅程中的所有可能的起点。我们所知道的每个地方都可以从中举动。

我们可以考虑一个作为第一步或第二步的旅程的两个步骤。所以我们代表这个或与工会代表。

一旦我们找到了我们的第一步和第二步,第三步就是与起点一样的第二步。 “路线”是到目前为止的部分之旅,我们寻找可行的连接步骤。

在这里,我们通过旅程连接了指示。沿着迄今为止旅行的路径,并追加下一个传输模式和下一个目的地。

选择作为起源,纽墙作为目的地,长度,路径|| ' - [' ||方法|| '] - >' ||纽普拉斯罗出来的指示;

选择作为起源,纽墙作为目的地,长度,路径|| ' - [' ||方法|| '] - >' ||纽普拉斯罗出来的指示;

学习SQL井可以是一个有价值的时间投资。这是广泛使用的语言,跨越许多底层技术。

通过将你的思想从“我怎样才能收到我的数据,以便”我可以回答“来”来“以”来“以”如何以这种语言表达我的问题?“来充分利用它。” 让数据库弄清楚如何最好地回答问题。 它最为了解可用数据和手头的资源。