服务台数据库设计(Help Desk Database Design)
我所在的公司对于服务台系统有着非常特殊和独特的需求,所以没有任何开源系统能够为我们工作。 既然如此,我使用PHP和MySQL创建了一个自定义系统。 它远非完美,但比上一次使用的系统要好得多。 相信我! 它很好地满足了我们大部分的需求,但是我对数据库设置的方式有疑问。 这里是主要表格:
ClosedTickets ClosedTicketSolutions Locations OpenTickets OpenTicketSolutions Statuses Technicians
当用户提交帮助请求时,它将进入“OpenTickets”表。 当技术人员处理这个问题时,他们会提交条目并描述他们所做的事情。 这些条目放在“OpenTicketSolutions”表中。 问题解决后,处理该问题的最后一位技术人员将关闭该故障单并将其移至“ClosedTickets”表。 所有解决方案条目也都移到“ClosedTicketSolutions”表中。 其他表(位置,状态和技术人员)作为标准化手段存在(每个位置,状态和技术人员都有一个被引用的ID)。
我现在遇到的问题是这样的:
当我想查看所有打开的故障单的列表时,SQL语句有点复杂,因为我必须离开“位置”,“状态”和“技术人员”表。 来自各种表格的字段也需要可搜索。 查看SQL语句搜索由任何名字中包含“John”的人提交的门票的封闭门票有多复杂:
SELECT ClosedTickets.*, date_format(ClosedTickets.EntryDate, '%c/%e/%y %l:%i %p') AS Formatted_Date, date_format(ClosedDate, '%c/%e/%y %l:%i %p') AS Formatted_ClosedDate, Concat(Technicians.LastName, ', ', Technicians.FirstName) AS TechFullName, Locations.LocationName, date_format(ClosedTicketSolutions.EntryDate, '%c/%e/%y') AS Formatted_Solution_EntryDate, ClosedTicketSolutions.HoursSpent AS SolutionHoursSpent, ClosedTicketSolutions.Tech_ID AS SolutionTech_ID, ClosedTicketSolutions.EntryText FROM ClosedTickets LEFT JOIN Technicians ON ClosedTickets.Tech_ID = Technicians.Tech_ID LEFT JOIN Locations ON ClosedTickets.Location_ID = Locations.Location_ID LEFT JOIN ClosedTicketSolutions ON ClosedTickets.TicketNum = ClosedTicketSolutions.TicketNum WHERE (ClosedTickets.FirstName LIKE '%John%') ORDER BY ClosedDate Desc, ClosedTicketSolutions.EntryDate, ClosedTicketSolutions.Entry_ID
我现在无法做的一件事是同时搜索开放票和封闭票。 我不认为工会会适用于我的案子。 所以我想知道是否应该将打开和关闭的票据存储在同一个表中,并且只需要一个指示是否关闭票证的字段。 我可以预见的唯一问题是我们已经有很多已关闭的门票(将近30,000个),因此整个系统可能会执行得很慢。 将开放票和封闭票结合起来会不是个好主意?
The company I work at has very specific and unique needs for a help desk system, so none of the open source systems will work for us. That being the case, I created a custom system using PHP and MySQL. It's far from perfect, but it's infinitely better than the last system they were using; trust me! It meets most of our needs quite nicely, but I have a question about the way I have the database set up. Here are the main tables:
ClosedTickets ClosedTicketSolutions Locations OpenTickets OpenTicketSolutions Statuses Technicians
When a user submits a help request, it goes in the "OpenTickets" table. As the technicians work on the problem, they submit entries with a description of what they've done. These entries go in the "OpenTicketSolutions" table. When the problem has been resolved, the last technician to work on the problem closes the ticket and it gets moved to the "ClosedTickets" table. All of the solution entries get moved to the "ClosedTicketSolutions" table as well. The other tables (Locations, Statuses, and Technicians) exist as a means of normalization (each location, status, and technician has an ID which is referenced).
The problem I'm having now is this:
When I want to view a list of all the open tickets, the SQL statement is somewhat complicated because I have to left join the "Locations", "Statuses", and "Technicians" tables. Fields from various tables need to be searchable as well. Check out how complicated the SQL statement is to search closed tickets for tickets submitted by anybody with a first name containing "John":
SELECT ClosedTickets.*, date_format(ClosedTickets.EntryDate, '%c/%e/%y %l:%i %p') AS Formatted_Date, date_format(ClosedDate, '%c/%e/%y %l:%i %p') AS Formatted_ClosedDate, Concat(Technicians.LastName, ', ', Technicians.FirstName) AS TechFullName, Locations.LocationName, date_format(ClosedTicketSolutions.EntryDate, '%c/%e/%y') AS Formatted_Solution_EntryDate, ClosedTicketSolutions.HoursSpent AS SolutionHoursSpent, ClosedTicketSolutions.Tech_ID AS SolutionTech_ID, ClosedTicketSolutions.EntryText FROM ClosedTickets LEFT JOIN Technicians ON ClosedTickets.Tech_ID = Technicians.Tech_ID LEFT JOIN Locations ON ClosedTickets.Location_ID = Locations.Location_ID LEFT JOIN ClosedTicketSolutions ON ClosedTickets.TicketNum = ClosedTicketSolutions.TicketNum WHERE (ClosedTickets.FirstName LIKE '%John%') ORDER BY ClosedDate Desc, ClosedTicketSolutions.EntryDate, ClosedTicketSolutions.Entry_ID
One thing that I'm not able to do right now is search both open and closed tickets at the same time. I don't think a union would work in my case. So I'm wondering if I should store the open and closed tickets in the same table and just have a field indicating whether or not the ticket is closed. The only problem I can forsee is that we have so many closed tickets already (nearly 30,000) so the whole system might perform slowly. Would it be a bad idea to combine the open and closed tickets?
原文:https://stackoverflow.com/questions/2539986
最满意答案
aggregate
是你的答案db.foo.aggregate({"$project" : {"two" : "$friends.two"}}).result
还有另一种方法可以做到这一点(获得不同的价值)
db.foo.aggregate([ {'$project': { union:{$setUnion:["$friends.two"]} } } ]).result;
aggregate
is your answerdb.foo.aggregate({"$project" : {"two" : "$friends.two"}}).result
there is another way to do that (getting distinct values)
db.foo.aggregate([ {'$project': { union:{$setUnion:["$friends.two"]} } } ]).result;
相关问答
更多-
MongoDB部分匹配对象(MongoDB partial match on object)[2021-08-11]
我认为这应该工作: db.tutorials.find({ $or: [ { "permissions.records": { $elemMatch: { $in: ["add", "delete"] } } }, { "permissions.folders": { $elemMatch: { $in: ["delete"] } } }, { "permissions.logs": { $elemMatch: { $in: ["add", "dele ... -
如何从mongodb中的字段中的对象数组中检索部分对象(how to retrieve partial objects from object array in a field in mongodb)[2021-09-18]
aggregate是你的答案 db.foo.aggregate({"$project" : {"two" : "$friends.two"}}).result 还有另一种方法可以做到这一点(获得不同的价值) db.foo.aggregate([ {'$project': { union:{$setUnion:["$friends.two"]} } } ]).result; aggregate is ... -
使用mongodb中对象字段的值创建新的数组字段(Create new array field with values from object field in mongodb)[2023-01-10]
我所要做的就是将一个函数传递给db.eval,如下所示: db.eval(function() {db.test.find({ class: 'x' }).snapshot().forEach( function (e) { e.urls2 = [{ url: e.urls.a, type: 'a'}]; db.test.save(e); } )}) 它工作 All I had to do was to pass a function to db.eval, like this: ... -
在mongoDB中如何达到对象数组中字段“name”的值(In mongoDB how to reach to value of the field “name” in the array of objects)[2021-06-22]
您可以通过提供嵌套属性的路径来搜索mongodb中的嵌套对象: db.YOURCOLLECTION.find({"friends.name": "ABC"}); 在这里阅读更多关于嵌套对象查询 也许这个领域需要在这个领域执行搜索之前索引? 当然你可以在嵌套字段上创建索引。 只要提供一个带有属性的索引就像上面的嵌套字段的路径: db.YOURCOLLECTION.createIndex( { "friends.name": 1 } ) 为了提前使用,您可以阅读$regex查询 You can search ... -
find(arg1) 命令您使用返回与存储在集合中的文档,因此它可以搜索嵌套的文档,但不能返回顶级集合文档的一部分。 它返回所有文档。 如果你的文档结构经常尝试使用它 find(arg1, arg2) 而是限制返回的字段https://docs.mongodb.org/manual/tutorial/project-fields-from-query-results/ 如果您的文档结构不规则,请使用您喜欢的编程语言编写脚本 After much research, I found a way of ac ...
-
检索MongoDB集合中对象数组中的查询元素(Retrieve the queried element in an object array in MongoDB collection)[2023-03-08]
使用Mongo 2.2+,您可以使用新的聚合框架 。 db.getCollection('models').aggregate([ { $unwind : "$grades.grades" }, { $match : {"dataPath": "/nissan/in/en/L02B", "grades.grades.key": "LVL002"}} ]) 展开从输入解构数组字段以输出每个元素的文档。 使用您发布的文档作为示例,通过展开,您将有4个文档。 然 ... -
嗨,你可以使用$ elemMatch来做到这一点。 这是一个工作样本 db.getCollection('users').find( {"cars": {$elemMatch: { "type": "hatchback","score": {$gte: 6} } } } ) 正如您所看到的,$ elemMatch的语法是 {
: { $elemMatch: { , 如何查询和删除MongoDB中数组字段中的嵌入对象?(How to query for and delete embedded objects in an array field in MongoDB?)[2021-10-02]
您可以将文档重组为此结构: { "_id" : ObjectId("581114330de9ac0c1445cdd6"), "user" : "test-username1", "likedQuizzes" : [ { "title" : "2 Purple", "author" : "purple-tester1", "date" : ISODate("2016-10-26T20:39:02.6 ...这实际上取决于你想要对订单做什么。 您是否需要查询聚合根? 相反,按日期查询实际订单是否有意义? 所以你最终得到: session.QueryOver().Where(t => t.OrderDate > ...); 如果您的关联设置正确,您仍然可以导航到该用户。 我个人认为存储库模式有点限制,宁愿使用查询对象,所以你最终得到的结果如下: queryService.FindAll (new GetAllByFilterOrderDate(DateTime.Now)); ... 根据高级查询文档 ,您可以使用点表示法混合数组值查询以进入对象 。 以下是使用您的架构的示例: $ mongo MongoDB shell version: 2.1.0 connecting to: test > db.users.save({_id: 1, friends: [{id: 2, name: 'bob'}]}) > db.users.find({friends: {id: 2, name: 'bob'}}) { "_id" : 1, "friends" : [ { "id" : 2, "nam ...相关文章
更多- HTML5 Web SQL Database 数据库
- HDFS Append 设计文档的QA(Questions about the “Append Design”)
- myEclipse8.5 New DataBase Connection Driver时出错
- 腾讯高级设计师谈微信的旧容与新妆,Android Design是大势所趋
- 《Oracle Database 11g DBA手册》(Oracle Database 11g DBA Handbook )扫描版[PDF]
- 《Oracle Database 11g SQL开发指南》(Oracle Database 11g SQL )扫描版[PDF]
- 《数据库系统基础:初级篇(第5版)》(Fundamentals of Database Systems (5th Edition))扫描版[PDF]
- 《数据库系统基础:高级篇(第5版)》(Fundamentals of Database Systems (5th Edition) )扫描版[PDF]
- 数据库设计 Step by Step (1)
- 电商平台数据库设计
最新问答
更多- 如何在Laravel 5.2中使用paginate与关系?(How to use paginate with relationships in Laravel 5.2?)
- linux的常用命令干什么用的
- 由于有四个新控制器,Auth刀片是否有任何变化?(Are there any changes in Auth blades due to four new controllers?)
- 如何交换返回集中的行?(How to swap rows in a return set?)
- 在ios 7中的UITableView部分周围绘制边界线(draw borderline around UITableView section in ios 7)
- 使用Boost.Spirit Qi和Lex时的空白队长(Whitespace skipper when using Boost.Spirit Qi and Lex)
- Java中的不可变类(Immutable class in Java)
- WordPress发布查询(WordPress post query)
- 如何在关系数据库中存储与IPv6兼容的地址(How to store IPv6-compatible address in a relational database)
- 是否可以检查对象值的条件并返回密钥?(Is it possible to check the condition of a value of an object and JUST return the key?)
- GEP分段错误LLVM C ++ API(GEP segmentation fault LLVM C++ API)
- 绑定属性设置器未被调用(Bound Property Setter not getting Called)
- linux ubuntu14.04版没有那个文件或目录
- 如何使用JSF EL表达式在param中迭代变量(How to iterate over variable in param using JSF EL expression)
- 是否有可能在WPF中的一个单独的进程中隔离一些控件?(Is it possible to isolate some controls in a separate process in WPF?)
- 使用Python 2.7的MSI安装的默认安装目录是什么?(What is the default installation directory with an MSI install of Python 2.7?)
- 寻求多次出现的表达式(Seeking for more than one occurrence of an expression)
- ckeditor config.protectedSource不适用于editor.insertHtml上的html元素属性(ckeditor config.protectedSource dont work for html element attributes on editor.insertHtml)
- linux只知道文件名,不知道在哪个目录,怎么找到文件所在目录
- Actionscript:检查字符串是否包含域或子域(Actionscript: check if string contains domain or subdomain)
- 将CouchDB与AJAX一起使用是否安全?(Is it safe to use CouchDB with AJAX?)
- 懒惰地初始化AutoMapper(Lazily initializing AutoMapper)
- 使用hasclass为多个div与一个按钮问题(using hasclass for multiple divs with one button Problems)
- Windows Phone 7:检查资源是否存在(Windows Phone 7: Check If Resource Exists)
- 无法在新线程中从FREContext调用getActivity()?(Can't call getActivity() from FREContext in a new thread?)
- 在Alpine上升级到postgres96(/ usr / bin / pg_dump:没有这样的文件或目录)(Upgrade to postgres96 on Alpine (/usr/bin/pg_dump: No such file or directory))
- 如何按部门显示报告(How to display a report by Department wise)
- Facebook墙贴在需要访问令牌密钥后无法正常工作(Facebook wall post not working after access token key required)
- Javascript - 如何在不擦除输入的情况下更改标签的innerText(Javascript - how to change innerText of label while not wiping out the input)
- WooCommerce / WordPress - 不显示具有特定标题的产品(WooCommerce/WordPress - Products with specific titles are not displayed)