我有一个简单的 mysql 表,用作服务器预订系统。如果用户拥有该服务器的有效预订,则他可以登录到该服务器。示例数据可能如下所示:
+----------+----------------+---------------------+---------------------+
| server | user | start | end |
+----------+----------------+---------------------+---------------------+
| server01 | Alice,Bob | 2013-10-28 00:00:00 | 2013-12-31 00:00:00 |
| server02 | Carlos | 2013-10-28 00:00:00 | 2013-12-31 00:00:00 |
| server03 | Dan,Erin,Frank | 2013-10-28 00:00:00 | 2013-12-31 00:00:00 |
+----------+----------------+---------------------+---------------------+
Run Code Online (Sandbox Code Playgroud)
要检查用户Carlos
是否预订了server02
,我使用以下 SQL 查询:
SELECT 0, id FROM booking WHERE user = 'Carlos'
AND (( start < now() and end > now() ) AND server = 'server02') ;
Run Code Online (Sandbox Code Playgroud)
但如果有多个(逗号分隔)用户,则此查询不起作用。如何查看是否Alice
有预订server01
?
我会过度考虑您的设计,并会更改为以下内容:
+--------+----------+
| UserID | Username |
+--------+----------+
| 1 | PAUL |
+--------+----------+
| 2 | Eric |
+--------+----------+
Run Code Online (Sandbox Code Playgroud)
+------------+------------------+
| ServerID | Servername |
+------------+------------------+
| 1 | Apache |
+------------+------------------+
| 2 | Nginx |
+------------+------------------+
Run Code Online (Sandbox Code Playgroud)
+-------------+-----------------+---------------+-------------+
| ServerID | UserID | Start | End |
+-------------+-----------------+---------------+-------------+
| 1 | 1 | somedate | somedate |
+-------------+-----------------+---------------+-------------+
| 2 | 1 | somedate | somedate |
+-------------+-----------------+---------------+-------------+
| 1 | 2 | somedate | somedate |
+-------------+-----------------+---------------+-------------+
Run Code Online (Sandbox Code Playgroud)
虽然您的booking
表非常需要对user
列进行标准化(严重、严重、可怕、重要等),但您可以在此期间执行以下操作...
SELECT 0, id FROM booking
WHERE ((start < now() and end > now())
AND server = 'server02') AND
LOCATE(',Alice,',CONCAT(',',user,',')) > 0;
Run Code Online (Sandbox Code Playgroud)
试一试 !!!
警告:请按照 Johnny000 刚刚建议的方式标准化您的数据!!!为什么???
您不会user
以 CSV 格式搜索任何体面的查询性能。
如果你 normalize user
,你的数据应该是这样的:
+----------+--------+---------------------+---------------------+
| server | user | start | end |
+----------+--------+---------------------+---------------------+
| server01 | Alice | 2013-10-28 00:00:00 | 2013-12-31 00:00:00 |
| server01 | Bob | 2013-10-28 00:00:00 | 2013-12-31 00:00:00 |
| server02 | Carlos | 2013-10-28 00:00:00 | 2013-12-31 00:00:00 |
| server03 | Dan | 2013-10-28 00:00:00 | 2013-12-31 00:00:00 |
| server03 | Erin | 2013-10-28 00:00:00 | 2013-12-31 00:00:00 |
| server03 | Frank | 2013-10-28 00:00:00 | 2013-12-31 00:00:00 |
+----------+--------+---------------------+---------------------+
Run Code Online (Sandbox Code Playgroud)
如果您进行归一化的重置,您应该得到以下信息:
+----+--------+
| id | name |
+----+--------+
| 1 | Alice |
| 2 | Bob |
| 3 | Carlos |
| 4 | Dan |
| 5 | Erin |
| 6 | Frank |
+----+--------+
Run Code Online (Sandbox Code Playgroud)
+----+----------+
| id | name |
+---------------+
| 1 | server01 |
| 2 | server02 |
| 3 | server03 |
+----+----------+
Run Code Online (Sandbox Code Playgroud)
+----------+--------+---------------------+---------------------+
| serverid | userid | start | end |
+----------+--------+---------------------+---------------------+
| 1 | 1 | 2013-10-28 00:00:00 | 2013-12-31 00:00:00 |
| 1 | 2 | 2013-10-28 00:00:00 | 2013-12-31 00:00:00 |
| 2 | 3 | 2013-10-28 00:00:00 | 2013-12-31 00:00:00 |
| 3 | 4 | 2013-10-28 00:00:00 | 2013-12-31 00:00:00 |
| 3 | 5 | 2013-10-28 00:00:00 | 2013-12-31 00:00:00 |
| 3 | 6 | 2013-10-28 00:00:00 | 2013-12-31 00:00:00 |
+----------+--------+---------------------+---------------------+
Run Code Online (Sandbox Code Playgroud)
您可以booking
像这样在表上创建索引:
ALTER TABLE booking
ADD INDEX user_server_ndx (userid,serverid),
ADD INDEX server_user_ndx (serverid,userid),
ADD INDEX start_end_ndx (start,end),
ADD INDEX end_ndx (end)
;
Run Code Online (Sandbox Code Playgroud)
也许您不需要所有这些索引,但您可以决定哪些不需要。
归档时间: |
|
查看次数: |
5624 次 |
最近记录: |