MySQL性能:具有多种类型的单个对象 - JOIN场景

时间:2016-08-23 20:34:57

标签: mysql performance oop

使用以下类型的表格设计:

http://www.martinfowler.com/eaaCatalog/classTableInheritance.html

为了举例,我们使用以下模式:

CREATE TABLE `fruit` (
  `id` int(10) UNSIGNED NOT NULL,
  `type` tinyint(3) UNSIGNED NOT NULL,
  `purchase_date` DATETIME NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `apple` (
  `fruit_id` int(10) UNSIGNED NOT NULL,
  `is_macintosh` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `orange` (
  `fruit_id` int(10) UNSIGNED NOT NULL,
  `peel_thickness_mm` decimal(4,2) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


ALTER TABLE `fruit`
  ADD PRIMARY KEY (`id`);

ALTER TABLE `apple`
  ADD KEY `fruit_id` (`fruit_id`);

ALTER TABLE `orange`
  ADD KEY `fruit_id` (`fruit_id`);


ALTER TABLE `fruit`
  MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT;

ALTER TABLE `apple`
  ADD CONSTRAINT `apple_ibfk_1` FOREIGN KEY (`fruit_id`) REFERENCES `fruit` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

ALTER TABLE `orange`
  ADD CONSTRAINT `orange_ibfk_1` FOREIGN KEY (`fruit_id`) REFERENCES `fruit` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

在这里,'apple'和'oranges'是'fruit'的类型,并且具有独特的属性,这就是为什么它们被分割成自己的表格。

问题是,从性能角度来看,在执行SELECT * FROM fruit查询时,最好是:

a)在每个类型表上执行LEFT OUTER JOIN,即appleorange(实际上,我们可能会处理数十种水果类型)

b)跳过联接并稍后对应用程序逻辑中的每个fruit行执行单独的查询,因此对于fruitapple行,SELECT * FROM apple WHERE fruit_id=...

编辑: 关于具体方案,我不会详细讨论,但这里的实际应用是一个通知系统,它会在某些事件发生时生成通知。每种事件类型都有不同的通知类型,每种通知类型都存储该事件类型的唯一属性。这是在具有大量用户活动的站点上,因此最终将有数百万个通知行。

1 个答案:

答案 0 :(得分:1)

有一个表格包含'common'属性的列(例如,type ='apple',purchase_date = ...),另外还有一个package application; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Image; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.PdfPCell; import com.itextpdf.text.pdf.PdfPTable; import com.itextpdf.text.pdf.PdfWriter; import org.apache.commons.io.FilenameUtils; import org.apache.poi.hslf.model.Slide; import org.apache.poi.hslf.usermodel.SlideShow; import org.apache.poi.xslf.usermodel.XMLSlideShow; import org.apache.poi.xslf.usermodel.XSLFSlide; public class PPView { public static void showPowerPoint(File sFiles) throws Exception { File file = new File(sFiles.getAbsolutePath()); String name=file.getName(); String destination= file.getAbsolutePath(); String outDestination=file.getParent(); String fileType=FilenameUtils.getExtension(destination); FileInputStream is = new FileInputStream(file); double zoom = 2; AffineTransform at = new AffineTransform(); at.setToScale(zoom, zoom); Document pdfDocument = new Document(); FileOutputStream outputStream = new FileOutputStream(outDestination+name+".pdf"); PdfWriter pdfWriter = PdfWriter.getInstance(pdfDocument, outputStream); PdfPTable table = new PdfPTable(1); pdfWriter.open(); pdfDocument.open(); Dimension pgsize = null; Image slideImage = null; BufferedImage img = null; if (fileType.equalsIgnoreCase(".ppt")) { SlideShow ppt = new SlideShow(is); pgsize = ppt.getPageSize(); Slide slide[] = ppt.getSlides(); pdfDocument.setPageSize(new Rectangle((float) pgsize.getWidth(), (float) pgsize.getHeight())); pdfWriter.open(); pdfDocument.open(); for (int i = 0; i < slide.length; i++) { img = new BufferedImage((int) Math.ceil(pgsize.width * zoom), (int) Math.ceil(pgsize.height * zoom), BufferedImage.TYPE_INT_RGB); Graphics2D graphics = img.createGraphics(); graphics.setTransform(at); graphics.setPaint(Color.white); graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height)); slide[i].draw(graphics); graphics.getPaint(); slideImage = Image.getInstance(img, null); table.addCell(new PdfPCell(slideImage, true)); } } if (fileType.equalsIgnoreCase(".pptx")) { XMLSlideShow ppt = new XMLSlideShow(is); pgsize = ppt.getPageSize(); XSLFSlide slide[] = ppt.getSlides(); pdfDocument.setPageSize(new Rectangle((float) pgsize.getWidth(), (float) pgsize.getHeight())); pdfWriter.open(); pdfDocument.open(); for (int i = 0; i < slide.length; i++) { img = new BufferedImage((int) Math.ceil(pgsize.width * zoom), (int) Math.ceil(pgsize.height * zoom), BufferedImage.TYPE_INT_RGB); Graphics2D graphics = img.createGraphics(); graphics.setTransform(at); graphics.setPaint(Color.white); graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height)); slide[i].draw(graphics); graphics.getPaint(); slideImage = Image.getInstance(img, null); table.addCell(new PdfPCell(slideImage, true)); } } pdfDocument.add(table); pdfDocument.close(); pdfWriter.close(); System.out.println("Powerpoint file converted to PDF successfully"); } } 列,其中TEXT包含任何其他属性(例如,subtype ='macintosh')适合所讨论的行。

或者将JSON作为一个共同的属性可能更有意义,因为很多水果都有这样的(想想'肚脐')。

你将如何处理“继承”?它在教科书中很棒,但它在数据库中很糟糕。 SQL早于继承,面向对象等等。