龙纹身女孩和 SQL
openkk 12年前
<div id="OSChina_News_29735" class="NewsContent TextContent NewsType2"> <p>我喜欢大卫·芬奇(David Fincher)拍的电影《龙纹身女孩》,他成功的把小说《<a href="/misc/goto?guid=4958343143198588913">龙纹身女孩</a>》搬上了荧幕,超出了我的预期。我本以为这又是一部肤浅的、愤世嫉俗的用来敛钱的好莱坞电影,事实情况却是,这是一部情节紧张,能引起共鸣的电影,只是里面的淫杀犯罪让人毛骨悚然。我最喜欢的一个情节是龙纹身女孩用SQL来查找40年前的凶杀案的过程。</p> <p><img class="alignnone size-large wp-image-4226" title="龙纹身女孩" alt="龙纹身女孩和 SQL" src="https://simg.open-open.com/show/e283f644ad3fa378b172b9af50d0b1eb.jpg" width="560" height="304" /></p> <p>我们从电影里可以看到她使用笔记本电脑,轻而易举的进入瑞典警察局数据库,当她敲入像‘unsolved(未破案)’和‘decapitation(斩首)’等关键词时,屏幕上翻滚着绿色的检索出的信息,虽然我们看不清她使用的完整的查询语句:</p> <p><img class="alignnone wp-image-4222" title="sql1" alt="龙纹身女孩和 SQL" src="https://simg.open-open.com/show/5cf98f4372da95df8e18afcb86826dd9.jpg" width="300" height="199" /><img class="alignnone wp-image-4221" title="sql2" alt="龙纹身女孩和 SQL" src="https://simg.open-open.com/show/4fc49b59844f971965e33a3fcf6a0f2d.jpg" width="300" height="199" /></p> <p>处于一种天生的好奇,我忍不住截取了这些镜头画面,用Photoshop拼接了一下,下面是我得到的结果:</p> <p><img class="alignnone size-large wp-image-4223" title="完整sql" alt="龙纹身女孩和 SQL" src="https://simg.open-open.com/show/ec49565984ff533e20d540fc3beacf2b.jpg" width="560" height="120" /></p> <p>你马上能发现,这不是Oracle SQL——很显然 <code>AS</code> 关键字在Oracle里不能用在表假名上。事实上,如果我们回去看看她那个令人兴奋的查询结果输出时,你会看到 <code>mysql</code> 的提示符,而且还有 <code>use [dbname]</code> 连接数据库的语法,下面是一个更详细的画面:</p> <p><img class="alignnone size-large wp-image-4219" title="全屏显示" alt="龙纹身女孩和 SQL" src="https://simg.open-open.com/show/ccadb1a39693f56eec441ea11e2a9842.jpg" width="560" height="372" /></p> <p>我们实际上可以把她用的left join关键词表的SQL语句整理出来。</p> <p>最终我们获得了一个全屏的输出结果信息:</p> <p><img class="alignnone size-large wp-image-4220" title="详细输出图" alt="龙纹身女孩和 SQL" src="https://simg.open-open.com/show/19c42f0db88de31b9c0e0fa7103278eb.jpg" width="560" height="311" /></p> <p>下面就是我们Oracle“WTF研究会”部门重新构造出的她使用的SQL:</p> <pre>SELECT DISTINCT v.fname, v.lname, i.year, i.location, i.report_file FROM Incident AS i LEFT JOIN V(ictim?)... <em>-- presumably v.incident_id = i.id</em> LEFT JOIN Keyword AS k ON k.incident_id = i.id WHERE i.year BETWEEN 1947 AND 1966 AND i.type = 'HOMICIDE' AND v.sex = 'F' AND i.status = 'UNSOLVED' AND ... OR v.fname IN ('Mari', 'Magda') OR SUBSTR ... AND (k.keyword IN ('rape', 'decapitation', 'dismemberment', 'fire', 'altar', 'priest', 'prostitute') ... AND SUBSTR(v.fname, 1, 1) = 'R' AND SUBSTR(v.lname, 1, 1) = 'L'); +--------+---------+------+-----------+----------------------------------+ | fname | name | year | location | report_file | +--------+---------+------+-----------+----------------------------------+ | Anna | Wedin | 1956 | Mark | FULL POLICE REPORT NOT DIGITIZED | | Linda | Janson | 1955 | Mariestad | FULL POLICE REPORT NOT DIGITIZED | | Simone | Grau | 1958 | Goteborg | FULL POLICE REPORT NOT DIGITIZED | | Lea | Persson | 1962 | Uddevalla | FULL POLICE REPORT NOT DIGITIZED | | Kajsa | Severin | 1962 | Dals-Ed | FULL POLICE REPORT NOT DIGITIZED | +--------+---------+------+-----------+----------------------------------+</pre> <p>你也许会很惊讶,很奇怪,这样一个顶级的黑客为什么要outer-join的方式连接Victims(被害人)表和Keywords(关键词)表呢,还使用这样的文字过滤方式,岂不知MySQL里是有 <code>like</code> 语法的,更奇怪的是输出结果里根本没有姓和名分别以’R L’打头的受害人。</p> <p id="page-note">[本文英文原文链接:<a href="/misc/goto?guid=4958343144020464700">The Girl With The ANSI Tattoo</a> ]<br /> <br /> 本文转载自: 外刊IT评论 <a href="/misc/goto?guid=4958183272158702965" rel="nofollow" target="_blank">http://www.aqee.net/</a> </p> </div>