我在我的 Web 应用程序中使用 mysql。应用程序表包含主管表和员工表。员工表包含有关每个员工的信息。 supervisor 表包含如下两列。
supervisor_id -> which is employee id of the supervisor
subordinate_id -> which is the employee id of the subordinate.
每个下属可以有多个主管,一个主管的下属可以是其他员工的主管。所以表记录可以如下。
supervisor_id | subordinate_id
1 | 2
1 | 3
2 | 4
4 | 5
3 | 6
3 | 4
在上面的例子中有一个主管链。主管 1 有 2、3、4、5 和 6 作为他的下属。主管 2 有 4、5 个下属。一个下属也可以有多个主管。
当我当前查询主管 2 的所有下属时,我使用如下查询。
public function getSubordinate($id) {
$query = "SELECT * FROM supervisor WHERE subordinate_id = $id";
// get results and return
}
所以我目前要做的是首先将 id 作为 2 发送以获取其直属下属。然后对于每个结果下属,我一次又一次地运行查询以获得完整的下属链。
这对于少量数据来说是可以的。但是这个主管表将有数千条数据,所以我必须进行数千次查询才能找到主管链,而且要花很多时间才能给出结果。
由于下属可以有多个主管,因此嵌套集不是这个问题的确切答案。
我也经历了这个解决方案。 http://www.codeproject.com/Articles/22824/A-Model-to-Represent-Directed-Acyclic-Graphs-DAG-o
但是当我使用这种方法时,该表将包含数百万条数据。而且效率低下。
我的问题是有什么有效的方法可以做到这一点。我的表结构是否有任何问题导致我无法有效地执行此类查询。
最佳答案
所有主要的数据库应用程序(包括 MySQL 和 MariaDB)现在都支持使用公用表表达式的递归查询。这是在 MySQL 8.0 版和 MariaDB 10.2.2 版中引入的。 PostgreSQL 的支持甚至更早。 Oracle 有它,SQL Server 在 2005 版本中添加了它。事实上,快速搜索表明 Sqlite 也支持公用表表达式。
因此,您可能正在寻找的答案是使用公用表表达式和递归查询。与“A Model to Represent Directed Acyclic Graphs (DAG) on SQL Databases”相比,这被认为是更好的解决方案的一些原因解释如下:
在关系模型中编码和查询图
https://drtom.ch/posts/2012/02/11/Encoding_and_Querying_Graphs_in_the_Relational_Model/
(您可以忽略他所说的部分,“它不会特别在 MySQL 或 sqlite3 上运行,它们根本不支持 CTE。”正如我提到的,情况已不再如此。)
正如您在问题中指出的那样,“当我使用这种方法时,该表将包含数百万条数据。”如果您要以空间换取效率,那么仅此一项可能还不错,但正如 Tom 博士的帖子在一个示例中所解释的那样:
The operation of deleting or inserting the red arc requires effort in θ(n^2) too.
这是这些操作的 n 平方工作量;您获得了查询效率,但代价是空间效率低下和插入/删除效率低下。他进一步指出
practically all large real world networks are sparse. They have much fewer edges than there would be possible, i.e. m«n^2.
公平地说,您链接的 Kemal Erdogan 的代码项目文章来自 2008 年; CTE 那时还不是普遍可用的。此外,埃尔多安在权衡方面做出了明智的选择,他在这里解释道:
The solution that I have is based on a recursion [too]. However, instead of deferring the recursion until query time, I do the recursion at the insertion time, assuming that the graph is actually more queried than modified (which is true for all the cases that I have faced so far).
如果在阅读 Tom 博士的文章后,您最终更喜欢 Erdogan 的权衡,您可以通过在此处查看 Laravel 的实现来限制其他低效率:
GitHub - telkins/laravel-dag-manager:Laravel 的基于 SQL 的有向无环图 (DAG) 解决方案。 https://github.com/telkins/laravel-dag-manager
特别是,查看 Max Hops 并在您自己的解决方案中实现类似的东西。
这是在 Laravel 配置文件中:
/*
|--------------------------------------------------------------------------
| Max Hops
|--------------------------------------------------------------------------
|
| This value represents the maximum number of hops that are allowed where
| hops "[i]ndicates how many vertex hops are necessary for the path; it is
| zero for direct edges".
|
| The more hops that are allowed (and used), then the more DAG edges will
| be created. This will have an increasing impact on performance, space,
| and memory. Whether or not it's negligible, noticeable, or impactful
| depends on a variety of factors.
*/
'max_hops' => 5,
免责声明:我现在才为自己研究这个。我还没有任何这些解决方案的经验。
关于mysql - 如何高效查询有向无环图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11152891/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为