2014-11-08 26 views
5

Zaman serilerini bir MySQL veritabanında depolamak istiyorum. Bunu lineer bir şekilde yapmak isterim, yani her sıra benzersiz bir gözlem (1 ölçü, 1 site, 1 zaman damgası) anlamına gelir. Şu anda, 84 096 000 satır gerektirecek ve yılda yaklaşık 2 102 400 satır büyüyecek. Zaman serisi tablosu, indeksler ve ilgili sorguların (temel olarak ölçü, alan ve zaman aralığının belirlendiği bir veri seçimi) doğru bir şekilde tasarlanması için ne gibi önlemler alınmalıdır.Zaman tablosu veritabanı doğrusal depolama alanı

Düzenleme:

masa tasarımının bir öneri Ekleme: Sağlanan ölçün ve Site tablo var

CREATE TABLE TimeSeries(
    Id     INT   NOT NULL  AUTO_INCREMENT, 
    MeasureTimeStamp DATETIME  NOT NULL, 
    MeasureId   INT   NOT NULL, 
    SiteId    INT   NOT NULL, 
    Measure    FLOAT  NOT NULL, 
    Quality    INT   NOT NULL, 
    PRIMARY KEY (Id), 
    CONSTRAINT UNIQUE (MeasureTimeStamp,MeasureId,SiteId), 
    FOREIGN KEY (MeasureId) REFERENCES Measure(Id), 
    FOREIGN KEY (SiteId) REFERENCES Site(Id) 
); 
CREATE INDEX ChannelIndex ON TimeSeries(MeasureId,SiteId); 

, bu yapıya geliştirilmeli ya benim büyük sorguları ise:

SELECT * 
FROM TimeSeries 
WHERE (MeasureId IN (?,?,?)) 
    AND (SiteId IN (?,?,?)) 
    AND (MeasureTimeStamp BETWEEN ? AND ?) 
ORDER BY MeasureId ASC, 
     SiteId ASC, 
     MeasureTimeStamp ASC; 

Düzenleme 2:

Siteler yaklaşık 20'dir ve önlemler yaklaşık 50'dir. Bu, maksimum 1000 kanala (alan ve ölçü çifti) yol açar. Birkaç on yıl içinde biraz artabilir ancak 10000'den fazla kanala ulaşamaz. Verilerin çoğu yaklaşık 30 dakikalık bir zaman granülitesine sahiptir. Neyse zaman granülite sabit değildir ve bir dakikadan daha küçük olmayacaktır (bazı veriler günlük veya haftalıktır).

+0

MySQL kolayca işleyebilir. Ne tür WHERE cümleleri bekliyorsunuz? Minimal, "site" için bir dizin. – mainstreetmark

+0

'WHERE' maddesi, en azından, 'IN' listesi ölçütü (bu sütunlar elbette dizine eklenecektir) ve' BETWEEN 'kullanarak' timestamp '(' index ') kullanılarak 'site' ve' measure' iki yabancı anahtar üzerinde seçim yapacaktır. birincil anahtarın bir kısmı). – jlandercy

+0

Daha sonra hem 'site' hem de 'measure' ile bir dizin oluşturmanızı öneriyorum. Bu iki sütun, sonuçları verimli olacak kadar azaltacaktır. Karıştırmaya Timestamp eklerseniz, dizininizde veri tablosunda olduğu kadar çok satır bulunur ve MySQL bunu göz ardı eder. – mainstreetmark

cevap

1

Bazı ipuçları:

  • MySQL bir dizin için 'endeks sütunlar' tarafından sipariş birincil anahtarların bir listedir. Bu listeyi, ihtiyacınız olan değerleri bulmak için olabildiğince kolay bir şekilde sipariş etmek istersiniz.
  • MySQL, bir defada bir tabloda yalnızca bir dizin kullanır.
  • MySQL dizini soldan sağa (MySQl Multi-column indexes) kullanabilir. Bu, Endeks (A, B, C), WHERE A=? AND B=? yapmanıza, ancak WHERE B=? AND C=? yapmanıza olanak tanır. Örnekte

, dört endeksleri oluşturulur:

  • MeasureId,SiteId (ChannelIndex)
  • MeasureTimeStamp,MeasureId,SiteId (benzersiz kısıtlama)
  • MeasureId (yabancı anahtar)
  • SiteId (yabancı anahtar)

Simp ly koymak, ChannelIndex MeasureId ve SiteId birleştiren dizelerin bir listesi gibi sıralanır. Örneğin. MeasureId = 12 ve Site ID = 68 için sıralama değerini 12_68 olarak düşünebilirsiniz. Benzersiz kısıtınız, 2014-12-23 09:01:43_12_68 gibi değerlere göre sıralanır.

Sorgunuzu çözmek için MySQL dizini veya benzersiz kısıtlamayı kullanabilir. Seçtiğiniz tablonuzdaki verilere göre değişir. Bununla birlikte, optimal değildir. İndeksi kullanarak, MeasureId ve SiteId dizinine sahip olan dizindeki blokları hızla bulacaktır, ancak MeasureTimeStamp'un menzil içinde olup olmadığını kontrol etmek için ana tabloda her bir değere gitmesi gerekecektir. Benzersiz kısıtlamayı kullanarak zaman aralığını kolayca seçebilirsiniz. Bu dizin alt kümesi, yine de MeasureTimeStamp tarafından sipariş edildiği gibi MeasureId ve SiteId rastgele sipariş vermiştir.

sizin yapısını iyileştirmek için,

KISITLAMA UNIQUE (MeasureId, siteid, MeasureTimeStamp)

için benzersiz kısıtlamayı değiştirmek için yardımcı olacaktır Bu indeks olacak şimdi sıralama 12_68_2014-12-23 09:01:43 gibi değerlerle ki ben MySQL'in artık endeksteki ayrık ve tahmin edilebilir bir dizi aralığı seçebilmesiyle daha iyi performans göstermeyi bekliyoruz. Bu, SELECT ifadenizi kapsar ve dizininizi aynı anda yedekler.

İlgili konular