2017-02-22 38 views
0

所以我建立在MySQL數據庫中包含約20,000臺,每個人的基因,每個基因的表有一列列出了該基因中找到的替代名稱(同義詞)的文獻,而且往往沒有這些同義詞的邏輯,它們純粹出於歷史原因而存在。MySQL數據庫擁有數千臺

首先,有沒有更好的方式來建立這個數據庫以更少的表?

問題是,每個基因有不同數量的替代名稱,所以它不像我可以製作一個大表,每行對應一個基因和一定數量的列。即使每個基因具有相同數量的替代名稱,任何特定的列基本上都沒有意義,例如,第1列中的基因1的同義詞與第1列中的基因2的同義詞之間沒有關係。

到底是壞關於其在MySQL萬的表是什麼?

我可能會把數據庫分成23個數據庫(每個染色體一個),或者類似的東西,然後每個數據庫只有900個表格,這樣會更好嗎?

我幾乎覺得自己也許MySQL的(關係數據庫)是錯誤的工作工具。如果是這樣的話,那麼更好的數據庫範例是什麼?

+6

我會創建一個「基因」表,然後將另一個表與基因的id「交替」作爲外鍵。 – Jaime

+0

@Jaime你是指所有基因的一個全局「替代」表?然後使用特定基因的外鍵在這個「替代」表中查找其關聯的同義詞? – Thoth

+0

和一張染色體表。 –

回答

2

20,000表是很多表。如果您實際需要20,000張桌子,那麼沒有任何關於擁有20,000張桌子的「壞事」。我們使用innodb_file_per_table運行,所以這是一大堆文件,並且我們可能會在MySQL(innodb_open_filesopen_files_limittable_cache_open)中遇到一些限制,而這些限制又受到操作系統ulimit的限制。

再加上管理大量相同表的潛在困難。如果我需要添加一列,我需要將該列添加到20,000個表。這是20,000個ALTER TABLE語句。如果我錯過了一些表格,這些表格將不再相同。我只是不想去那裏,如果我可以幫助它。

我會建議並考慮一個不同的設計。

作爲第一個切口,這樣的:

CREATE TABLE gene_synonym 
(gene   VARCHAR(64) 
, synonym  VARCHAR(255) 
, PRIMARY KEY (gene, synonym) 
) ENGINE=InnoDB 
; 

要添加的代名詞的基因,而不是插入的值到一個特定的表的一列:

INSERT INTO gene_synonym (gene, synonym) VALUES ('alzwhatever','iforgot'); 

而查詢,而不是找出要查詢的20,000個表中的哪一個,我們將只查詢一個表,並在gene列上包括一個條件:

SELECT gs.synonym 
    FROM gene_synonym gs 
WHERE gs.gene = 'alzwhatever' 
ORDER BY gs.synonym 

WHERE子句使我們可以查看一個大表的子集,返回的集合將模擬當前單個表中的一個。

如果我需要搜索的代名詞,我可以查詢僅這一個表:

SELECT gs.gene 
    FROM gene_synonym gs 
WHERE gs.synonym = 'iforgot' 

要做到這一點相同的搜索20000個表,我需要20,000種不同進行選擇,一個爲每個每個20,000張桌子。

我只是在數據類型的贓物。由於MySQL的表名限制爲64個字符,因此我將gene列限制爲64個字符。

我們可以使用當前設計中表格的名稱填充基因列。

但是,該表無法模擬的是空表,即一個沒有任何同義詞的基因。 (或者,也許我們的設計將是該基因的名稱是自身的代名詞,所以我們就會有一個排('alzwhatever','alzwhatever')

無論哪種情況下,我們可能也想添加一個表是這樣的:

CREATE TABLE gene 
(gene   VARCHAR(64) 
, PRIMARY KEY (gene) 
) ENGINE=InnoDB 
; 

這是將有20000行的表,每一行對應一個在當前的設計中的表。

此外,我們還可以添加一個外鍵約束

ALTER TABLE gene_synonym 
ADD CONSTRAINT FK_gene_synonym_gene (gene) REFERENCES gene (gene) 
    ON UPDATE CASCADE ON DELETE CASCADE 
; 

這種設計更符合關係數據庫的規範模式。

這並不是說其他​​設計是「壞」的。只是這種設計會更典型。

+0

感謝您的好評!我有幾個問題,首先,在第三和第四代碼塊中'gs'的意義是什麼?它似乎沒有做任何事情,我可以離開它,一切似乎工作相同。其次,你能否用外鍵約束來解釋你的最後一段代碼?添加這個操作的效用是什麼?謝謝。 – Thoth

+0

在查詢中,'gs'是分配給表引用的短表別名。在這種情況下,別名不是必需的。在其他更復雜的查詢中,我們需要引入別名。但是我們限定*所有*列引用,並且使用短表別名是我們非常熟悉的有效模式。即使沒有特別要求,相同的模式也會傳遞給更簡單的查詢。外鍵約束是確保一致性的機制。它不允許將值分配給'gene_synonym'表中'gene'列中沒有出現在'gene'表中的'gene'列。 – spencer7593

2

你應該有一個同義詞表。 一個這樣的表:

create table geneSynonyms (
    geneSynonymId int auto_increment primary key, 
    geneId int not null, 
    synonym varchar(255), 
    constraint fk_geneSynonyms_geneId foreign key (geneId) references genes(geneId), 
    constraint unq_geneSynonyms_synonym unique (synonym) -- I assume this is unique 
); 

然後,你必須爲每個同義詞在一個表中的所有基因一行。

什麼是不好有成千上萬的表?這裏有幾件事:

  • 數據存儲效率非常低。表佔用的最小空間是一個數據頁面。如果你沒有填充頁面,你正在浪費空間。
  • 通過浪費空間,您最終會用幾乎空白的頁面填充頁面緩存。這意味着更少的數據適合內存,這會對性能產生不利影響。
  • 您的查詢硬連線到正在訪問的表。你不能爲多個基因編寫通用代碼。
  • 無法輕鬆更改數據結構。
  • 您無法驗證數據,因爲有規則說「同義詞在所有基因中必須是唯一的」。
  • 你不容易找到同義詞引用的基因。
  • 通過添加索引或分區數據來提高性能是一場噩夢。
相關問題