单表或多表规范化

时间:2012-09-15 18:12:47

标签: mysql database-design

我有一个问题可能很容易回答

我有一张图片表

图像可以有多种尺寸 - 更好的做法是拥有三个表

一张图表详细信息表 另一个将image_details连接到image_paths的表和另一个连接到图像路径的table- image_sizes。

或者最好将所有图像尺寸放在图像表中。实际上,我有一个图像,但大小不同。寻找优化的最佳选择。所有图像都具有每个图像尺寸,因此对于某些不具有特定尺寸的图像,将来不会有冗余。我不确定是否最好使用另一张桌子,以防我们添加其他尺寸。但是我可以在图像表中添加另一列以获得新的图像尺寸

Image_table

CREATE  TABLE IF NOT EXISTS `warrington_main`.`image` (  
  `id` MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT ,  
  `user_id` BIGINT(20) UNSIGNED NOT NULL ,  
  `alias_title` VARCHAR(255) NOT NULL ,  
  `address_id` BIGINT(20) NULL ,  
  `geolocation_id` BIGINT(20) NULL ,  
  `camera_id` MEDIUMINT(8) NULL ,  
  `title` VARCHAR(100) NOT NULL ,  
  `description` VARCHAR(2000) NOT NULL ,  
  `main_image` VARCHAR(50) NOT NULL ,  
  `thumbnail_image` VARCHAR(50) NOT NULL ,  
  `thumbnail_image_medium` VARCHAR(50) NOT NULL ,  
  `thumbnail_image_small` VARCHAR(50) NOT NULL ,  
  `thumbnail_image_gallery` VARCHAR(50) NOT NULL ,  
  `hits` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0' ,  
  `show_comment` ENUM('0','1') NOT NULL ,  
  `feature_in_gallery` ENUM('0','1') NOT NULL ,  
  `created_on` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' ,  
  `date_taken` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' ,  
  `updated_on` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' ,  
  `updated_by` BIGINT(20) UNSIGNED NOT NULL ,  
  `approved` ENUM('Inprocess','Yes','No') NOT NULL DEFAULT 'Inprocess' ,  
  `visible` ENUM('0','1') NOT NULL DEFAULT '0' ,  
  `account_type_created` ENUM('S','Y', 'G', 'FL', 'FB') NOT NULL ,  
  PRIMARY KEY (`id`) ,  
  UNIQUE INDEX `alias_title` (`alias_title` ASC) ,  
  INDEX `title` (`title` ASC) ,  
  INDEX `approved` (`approved` ASC) ,  
  INDEX `visible` (`visible` ASC) ,  
  INDEX `feature_in_gallery` (`feature_in_gallery` ASC) ,  
  INDEX `fk_image_image_user1_idx` (`user_id` ASC) ,  
  INDEX `fk_image_camera1_idx` (`camera_id` ASC) ,  
  INDEX `fk_image_address1_idx` (`address_id` ASC) ,  
  INDEX `fk_image_geolocation1_idx` (`geolocation_id` ASC) ,  
  INDEX `fk_image_user1_idx` (`updated_by` ASC) ,  
  CONSTRAINT `fk_image_image_user1`  
    FOREIGN KEY (`user_id` )  
    REFERENCES `warrington_main`.`user` (`id` )  
    ON DELETE NO ACTION  
    ON UPDATE NO ACTION,  
  CONSTRAINT `fk_image_camera1`  
    FOREIGN KEY (`camera_id` )    
    REFERENCES `warrington_main`.`camera` (`id` )  
    ON DELETE NO ACTION  
    ON UPDATE NO ACTION,  
  CONSTRAINT `fk_image_address1`  
    FOREIGN KEY (`address_id` )  
    REFERENCES `warrington_main`.`address` (`id` )
    ON DELETE NO ACTION  
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_image_geolocation1`  
    FOREIGN KEY (`geolocation_id` )  
    REFERENCES `warrington_main`.`geolocation` (`id` )  
    ON DELETE NO ACTION  
    ON UPDATE NO ACTION,  
  CONSTRAINT `fk_image_user1`    
    FOREIGN KEY (`updated_by` )    
    REFERENCES `warrington_main`.`user` (`id` )    
    ON DELETE NO ACTION    
    ON UPDATE NO ACTION)    
ENGINE = InnoDB    
AUTO_INCREMENT = 23162    
DEFAULT CHARACTER SET = utf8   

3 个答案:

答案 0 :(得分:1)

  

一个用于图像的表详细说明了另一个将image_details连接到image_paths的表和另一个连接到图像路径的table- image_sizes。

这不是规范化,并且被称为Vertical Partitioning,您希望对象的主要细节出现在一个表中,而辅助细节占用更多空间(通常)并且不属于一般过滤条件移动到不同的表。这样做是为了减少第一个表的每个记录的大小,这样每个数据库页面中的记录数量就会更多,因此在过滤期间要经过的页面数量会减少,IO和搜索能力也会提高。

在您的情况下,将图像的所有属性保留在单个表中似乎很好。

答案 1 :(得分:0)

您应该在使用多个表的情况下进行规范化,并且不要在多个地方存储相同的信息。这种冗余可以避免以后在任何应用程序生命周期中出现的数据问题。

因此,在您的情况下,IMAGE_SIZE应该是另一个IMAGE_ID作为外键定义的表。

IMAGE
    ID
    IMAGE_ATTRIBUTES

IMAGE_SIZE
    ID
    IMAGE_ID
    SIZE_ATTRIBUTES 

 IMAGE_PATH
    IMAGE_ID or IMAGE_SIZE_ID (depends)
    PATH 

答案 2 :(得分:0)

在这种情况下,一个表可能是处理它的方法。如果所有图像X都具有所有尺寸,并且您可能不会添加大量不同尺寸。

这三个表也可以正常工作,但是当你没有真正获益时,为什么要处理联接。

Images
    ImageDetailsId (PK)
    ImageSizeId (PK)
    URL
    ...

Image_Details
   ImageDetailsId
   ...

Image_Sizes (where this table is relatively static - small, medium, large..)
   ImageSizeID
   ... (width? height? etc?)