哪些列应该在mySQL数据库中编入索引?

时间:2014-11-27 18:42:39

标签: mysql database database-design

我正在尝试为我正在处理的程序设计数据库。在我发布程序之前,我希望设计完美无瑕,因为我听说一旦它发生就很难改变。总而言之,我的计划是一个买卖书籍的平台。用户可以在距离内搜索"在他们指定的搜索距离内查看是否有任何特定isbn的书籍。他们可以按价格或按日期列出书籍。我将在表格后面描述我的程序需要采取的行动:

BookListings (table)...

    userID VARCHAR(50) NOT NULL
    dateListed timestamp Default: CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    isbn13 VARCHAR(20) NOT NULL
    price UNSIGNED TINYINT NOT NULL
    email VARCHAR(30) NOT NULL
    phone VARCHAR(20) NOT NULL
    condition VARCHAR(30) NOT NULL
    latitude FLOAT(9,7) NOT NULL
    longitude FLOAT(9,7) NOT NULL

ContactInfo (table)...

   email VARCHAR(30) NOT NULL
   phone VARCHAR(20) NOT NULL

请记住,ContactInfo表并不是很重要。一旦我从数据库中移出信息以释放空间,我将经常清除它。如果这张桌子造成了很大的效率问题,我可以完全牺牲它,我也不会感到困扰。

BannedUsers (表格)......

  • userID VARCHAR(50) NOT NULL
  • banReason VARCHAR(50) NOT NULL

BannedUsers表是我要跟踪禁令的地方。它很少使用,但如果由于某种原因我想禁用某人使用我的程序,我可以将他们的userID放在那里。当我的程序启动时,它会检查BannedUsers表以查看用户是否被禁止,如果是,它会给他们禁止原因。

我有点困惑在哪里放置索引(我不太了解它们)。我只是听说索引极大地加速了搜索。对于我的BannedUsers,我认为将索引放在userID列上显而易见?如果是这样,什么样的指数?

对于BookListings表,我更容易混淆索引的位置。首先,我将解释我的程序的所有功能(要采取的操作)以及从我的PHP脚本中获取的查询:

  1. 我使用以下查询在我的系统中输入列表。这是为了当用户想要出售书籍时,他们会列出"列出"这本书。所以你可以想象这个动作会完成很多......
  2. INSERT INTO Listings
    VALUES ('$userID', (NOW() + INTERVAL 2 HOUR), '$isbn13', $price, '$email', '$phone', 
            '$condition', '$latitude', '$longitude')
    
    1. 当用户想要购买(搜索)与他们相距一定距离的图书清单时,我会使用以下查询。就像列出书籍的查询一样,这个动作也会被大量使用:
    2. SELECT
          *, (
            6371 * acos (
            cos ( radians($userLatitude) )
            * cos( radians( latitude ) )
            * cos( radians( longitude ) - radians($userLongitude) )
            + sin ( radians($userLatitude) )
            * sin( radians( latitude ) )
          )
      ) AS distance
      FROM Listings
      WHERE isbn13='$isbn13'
      HAVING distance <= $withinDistance
      ORDER BY price, dateListed
      

      以上查询是按价格订购的。以下查询按日期排序:

      SELECT
          *, (
            6371 * acos (
            cos ( radians($userLatitude) )
            * cos( radians( latitude ) )
            * cos( radians( longitude ) - radians($userLongitude) )
            + sin ( radians($userLatitude) )
            * sin( radians( latitude ) )
          )
      ) AS distance
      FROM Listings
      WHERE isbn13='$isbn13'
      HAVING distance <= $withinDistance
      ORDER BY dateListed DESC
      
      1. 在列出图书后立即进行以下查询。这是收集用户联系信息的一种方式:
      2. INSERT INTO ContactInfo
        VALUES ('$email', '$phone')
        
        1. 在程序开头使用以下查询来查找系统中列出的书籍数量(只是为了保持系统处理的书籍的有趣数量,而不是真正那么重要):
        2. SELECT COUNT(*) FROM ContactInfo
          
          1. 以下查询用于查找他们在系统中列出的所有用户的书籍。这将经常进行,因为他们需要在删除他们制作的列表之前这样做。它基本上用于向他们显示所有列表,然后他们选择要删除的列表:
          2. SELECT dateListed, isbn13, price 
            FROM Listings 
            WHERE userID='$userID' 
            ORDER BY dateListed DESC
            
            1. 以下是他们实际删除了商家信息的查询:
            2. DELETE FROM Listings WHERE userID='$userID' AND isbn13='$isbn13
              

              请帮助我提高设计效率。我不太确定索引的位置,因为我知道使用索引意味着它会更新和删除更难...我的程序也需要这样做。最初我想到索引isbn13(将被搜索的主要内容),但后来意识到我也将在纬度和经度上进行搜索,所以我不确定这些是否也必须被编入索引......这真的让人感到困惑我。请告诉我如何改进数据库的设计和查询。

1 个答案:

答案 0 :(得分:1)

没有免费的午餐。索引既有好处也有成本。

好处是一些操作会更快。

成本是某些操作会变慢,并且会消耗更多的磁盘空间和内存。

查找记录(包括查找更新和删除记录)会更快,但更新,删除和插入记录会更慢,因为索引需要更新。

您的查询目前是否缓慢?为什么?你需要查看你的执行计划,看看它们为什么慢。如果由于顺序扫描而导致它们很慢,则尝试添加索引。这会如何影响插入,删除和更新?值得花费吗?您是否有足够的磁盘空间和内存用于这些索引?这些是我们无法回答的问题。