Farklı tablolardaki verileri bir tablo halinde toplamak kötü bir uygulama mudur?


12

Arka fon

Ben büyük bir sağlık kayıtları DB (yazma SP'ler, fonksiyonlar, işler, vb.) İçin çok sayıda büyük raporlar yazarım ve genellikle saklarım. Orijinal şema ve onu kullanan yazılım farklı bir satıcıdan, bu yüzden yapısal olarak çok fazla değiştiremiyorum. Laboratuarlar, prosedürler, aşılar, vb.Gibi izleme gerektiren birçok kayıt vardır ve birçoğu şişirilmiş ve zayıf endekslenmiş düzinelerce tabloya dağılmıştır (Bunu biraz düzeltebildim).

Sorun

Sorun, DB üzerinde çok az kontrole sahip olduğumuz ve herhangi bir güncelleme veya yamadan değişebileceğinden, özellikle büyük miktarda çakışma olduğunda bu raporların yazılmasını ve sürdürülmesini zor ve sıkıcı hale getirmesidir. Tek gereken bir yama ve bir düzine raporun büyük bölümlerini yeniden yazmakta kaldım. Buna ek olarak, birleştirmeler, iç içe yerleştirmeler seçtikleri ve yığın oluşturdukça sorgular hızla gizlenir ve yavaşlar.

Çözümüm"

Planım, tüm bu kayıtları bir "tümünü yakala" tablosuna yazmak ve bu toplu tabloda kayıtları korumak için orijinal tablolara tetikleyiciler yazmaktı. Tabii ki, güncellemelerden sonra tetikleyicilerimin sağlam olduğundan emin olmalıyım, ancak bu sürdürülebilirlik açısından çok daha kolay ve sadece verileri referans alarak daha kolay olurdu.

Tablo ince ve uzun olacak, yalnızca gerekli verileri depolayacaktı:

CREATE TABLE dbo.HCM_Event_Log (
    id INT IDENTITY,
    type_id INT NULL,
    orig_id VARCHAR(36) NULL,
    patient_id UNIQUEIDENTIFIER NOT NULL,
    visit_id UNIQUEIDENTIFIER NULL,
    lookup_id VARCHAR(50) NULL,
    status VARCHAR(15) NULL,
    ordered_datetime DATETIME NULL,
    completed_datetime DATETIME NULL,
    CONSTRAINT PK_HCM_Event_Log PRIMARY KEY CLUSTERED (id)
)

Sonra type_id ve item groupings gibi şeyler için çeşitli ilişkisel tabloları olurdu.

Bu tabloların birçoğu biraz yazıldığından, bu fikri tahmin etmeye ikinci olarak başlıyorum, yazacağım SP'ler ve raporlar da verilere çok referans verecekti. Bu yüzden bu tablonun çok fazla G / Ç ile kayıt kilitleme ve performans kabusu haline gelmesinden endişe ediyorum.

Benim sorum

Kötü mü iyi bir fikir mi? SQL Server (2008 r2 Standard Edition BTW) ve "bazen" kuralında her durumun farklı olduğunu anlıyorum, ama gerçekten sadece genel tavsiye arıyorum.

Bir servis aracısı kullanmayı düşünmeye başladım, ancak yalnızca basit güncellemeler / ekler yapıyordum ( Kabul edilen cevaba alternatifi inceleyin ). Birçok durumda verilerin gerçek zamanlı olması gerekir, bu nedenle yedek bir DB kullanmak gerçekten işe yaramaz. Performans zaten bizim için bir sorun, ancak bunların çoğu yakında çözülecek olan donanımla ilgili.


1
Planlı kesintileri uygulayabilir misiniz? Bu güncellemelerden biri bir tetikleyiciyi silemezse ve büyük olasılıkla kötü verilere yol açan toplamalarınızı güncellemezseniz.
Erik

Laboratuvarlar, prosedürler, aşılar ve hastalar hakkındaki tüm bilgileri tek bir masaya koymayı mı düşünüyorsunuz? Kötü bir fikir. Çalıştırdığınız sorgu türlerine uygunsa bir yıldız şeması kullanabilirsiniz.
Michael Green

1
Bazı dizine alınmış görünümler oluşturmayı düşündünüz mü? Bunlar, kodunuzla satıcının arasına mantıksal bir katman yerleştirir, böylece satıcı altındaki şeyleri değiştirirse görünümü güncelleyebilirsiniz. Ayrıca, dizine eklenen görünümler sizin için önceden doldurulur ve iyi okuma performansı sağlar. Bunu yaparken en büyük etkenlerden biri, satıcının veritabanı tablolarının yazma işlemlerine ne kadar yük yüklediği. Ancak, bu, tetikleyicileri vb. Kullanmaktan daha temiz ve bakımı daha kolay bir çözüm olacaktır
Micah Nikkel

Geç cevap verenler için üzgünüm, geri bildiriminiz için teşekkürler. @Erik - Evet, güncellemeleri planladık ve yaptığım bir dizi kontrol listesi komut dosyası aracılığıyla önceki tüm değişikliklerimin hala yerinde olduğundan emin olmak için kontrol ediyorum, bu yüzden orada sürpriz olmayacak ve CREATE komut dosyalarını koruyacağım tüm tetikleyiciler.
jreed121

@MichaelGreen - Bir yıldız şemasına bakacağım, ama neden tüm bu verileri tek bir tabloda bulundurmanın kötü bir fikir olduğunu düşündüğünüzü merak ediyorum? Uygulama ortamı bir VPN'de tamamen izole edilmiştir, yine de ağın dışında erişilebilir değildir. Tabloda bir şeyler ters giderse, dünyanın sonu değil çünkü her şeyi ona geri yazabilirim. Tablo, kritik görev verileri için kullanılmaz veya en azından verilerin depolandığı tek veya birincil yer olmaz.
jreed121

Yanıtlar:


8

Eğer seni doğru anladıysam,

  • büyük bir üçüncü taraf sisteminiz var,
  • üzerinde çok fazla kontrole sahip değilsin,
  • doğrudan bu üçüncü taraf veritabanından veri okuyan karmaşık raporlar hazırlarsanız,
  • sorgularınız üçüncü taraf veritabanının iç yapısına bağlıdır.

Ben şöyle yaklaşırdım:

  • Tam kontrole sahip olduğum kendi ayrı veritabanımı kur.
  • Üçüncü taraf veritabanındaki ilgili tablolardan ve sütunlardan veri okuyan ve benimkine ekler / güncellemeler ekleyen bir senkronizasyon işlemi ayarlayın.
  • Veritabanımın kararlı yapısına dayalı olarak karmaşık raporlarımı geliştir.

Bu durumda, üçüncü taraf sistemi etkilemeden raporlarınızın performansını artırmak için veritabanınızın yapısına ve dizinlerine ince ayar yapabilirsiniz. Orijinal veri yapısı önemli ölçüde değişmedikçe, üçüncü taraf veritabanı değişirse raporlarınız için sorgularınızın mantığı değişmez. Yalnızca senkronizasyon işlemini ayarlamanız gerekir.

Senkronizasyon işlemi etkin bir şekilde dönüşüm sürecidir - verileri üçüncü taraf veritabanından ihtiyacınız olan yapıya dönüştürürsünüz. Bu dönüştürme işleminin bir kısmı, orijinal üçüncü taraf veritabanının sahip olabileceği normalleştirme sorunlarını çözebilir. Sistemin sadece bu kısmı, üçüncü taraf sistemin iç yapısını bilmek ve ona bağlı olmak zorundadır. Ana raporlarınız ve ana sorgularınız yalnızca veritabanınıza bağlıdır.

Yani, ana nokta - sisteminizin üçüncü taraf sistemin içlerine bağlı kısmını ayırın ve sınırlandırın.

Güncelleme

Gerçek zamanlı gereksinimle ilgili. BTW, her zaman "gerçek zamanlı" tanımının, "bazı küçük tepki süreleri" değil "garantili yanıt süreleri" olduğunu düşündüm. Tabii ki uygulamanıza bağlıdır. Uygulamamda, algılanan değişikliğin bir dakika içinde iki veritabanını senkronize etmem yeterli. Bir kullanıcı ekranda bir rapor görürse ve temelde yatan bazı veri değişiklikleri varsa, raporun bu değişikliği yansıtacak şekilde bir şekilde yeniden çalıştırılması gerekir. Değişiklikleri yoklayabilir veya bazı olay / mesajları dinleyebilirsiniz, yine de en son değişiklikleri göstermek için rapor sorgusunun tekrar yürütülmesi gerekir.

Orijinal tablolardaki değişiklikleri yakalamak için tetikleyiciler yazmak ve bu değişiklikleri bir genel tabloya yazmak istiyorsunuz. Bu nedenle, değişiklikleri istediğiniz gibi yakalayın, ancak bunları tek bir tabloya değil, normal olarak normalleştirilmiş tablolara yazın.

Yani, bu çok büyük bir durumdur - üçüncü taraf veri yapısının dahili veri yapınıza dönüştürülmesi INSERT/UPDATE/DELETE, üçüncü taraf tablolarını tetikleyen tetikleyicilerde gerçekleştirilir . Zor olabilir. Tetikleyicilerin kodu, her iki sistemin iç yapısına bağlı olacaktır. Dönüştürme önemsizse orijinali INSERT/UPDATE/DELETEhata noktasına kadar geciktirebilir . Tetikleyicinizde bir hata varsa, orijinal işlemi başarısız oldukları noktaya kadar etkileyebilir. Üçüncü taraf sistem değişirse, tetikleyici bozulabilir ve bu da üçüncü taraf sistem işlemlerinin başarısız olmasına neden olabilir.

Daha az uç durum. Tetikleyicilerinizin kodunu daha basit ve hatalara daha az eğilimli yapmak için, yakalanan tüm değişiklikleri bazı aşamalandırma / denetim / fark tablolarına yazın, bazı bayraklar ayarlayın / bekleyen değişiklikler olduğunu belirten bir mesaj gönderin ve gidecek ana dönüşüm işlemini başlatın bu aracı tablolar aracılığıyla dönüşüm gerçekleştirin. Buradaki en önemli şey, potansiyel olarak ağır dönüşüm sürecinin orijinal işlemin kapsamı dışında gerçekleşmesidir.

İkinci bir bakışta, sorudaki orijinal öneriniz gibi görünüyor. Ancak fark şu: Tüm yakalama tabloları verileri yalnızca geçici olarak tutar; veri miktarı azdır - değişenler; tek bir masa olması gerekmez; sonuçta veriler, tam kontrole sahip olduğunuz, üçüncü taraf sisteminden bağımsız olan ve sorgularınızı ayarlayabileceğiniz ayrı olarak normalleştirilmiş kalıcı tablolarda saklanacaktır.


Toplu aktarım rotasına gidiyorsanız, oldukça yüksek işlem sayılarında (günde 100K) Değişiklik İzleme (ve ihtiyaçlarınıza bağlı olarak Veri Yakalamayı Değiştirme) ile başarılı olduk. Kendi evreleme / denetim / diff tablolarınızı uygulamaktan daha kolaydır ve uygulama kodu değişikliği veya tetikleyiciler olmadan dağıtılabilir.
Michael Green

İster tetikleyiciler ister CDC olsun, gerçek zamanlıya gerçekten yaklaşmanın tek yolu akış veya kuyruktur. Kuyruk tabanlı gecikme ve maliyet etkinliği için iyi bir uzlaşmadır. Zamanınız kuyruğu daha hızlı işleme yöntemleri için harcanacaktır. işin büyük kısmını uygulamadan zaman uyumsuz olarak bırakarak ve kullanıcı işlemlerine daha az yük bindirir. Geçmişte, Allscripts Sunrise EMR'ye karşı, paralel paralel her C # çağrısı ile kuyruğu işleyen bir hizmetle bu şeyi yaptım. yeni verilerin işlenmesi ve depoda sunulması için tipik gecikme süresi 30 saniyenin
Brad D

Ben fazla "gerçek zamanlı" ifade etmiş olabilir, Milisaniye hatta 5 saniye ile çok ilgili değilim, ama personelimizin iş akışını yönlendirmek için güveniyor birçok sorgu var. Bir müşterinin kendilerine bir şey yapması halinde (prosedür, aşılama, vb.) Bunu kısa sürede göstermemiz gerekir. Dönüşümler önemsizdir ve / veya dönüşümler bile değildir. Ben sık sık değişmez gibi satıcı tablolarında değişiklik ile aşırı endişe değilim, ve ben zaten bunu yapmak zorunda, ama benim düşüncem güncelleme / bir düzinelerce rapor / sorgu daha bir yeniden oluşturmak daha kolay oldu / SP. Her güncellemeden sonra kontroller yapıyorum.
jreed121

@ jreed121, ben de düşünüyorum olduğu raporlardan daha güncelleme tetik (ler) daha kolay. Her kaynak tabloda değişiklikleri yakalamak için bir tetikleyiciniz olur, bu nedenle birden fazla tetikleyici olması muhtemeldir. Yine de, tüm bu yakalanmış değişiklikleri büyük bir denormalize tabloya yazmaya çalışmayın. Onları uygun şekilde normalleştirilmiş bir tablo kümesine yazın. Raporlarınız kontrol etmek ve gerektiği bu normalleştirilmiş tablolar dayanmalıdır değil değişebilir orijinal tablolar bağlıdır.
Vladimir Baranov

3

Elbette, karmaşık raporları ve sorguları değiştirmek yerine içe aktarma aşamasını değiştirebilmeniz için standart bir tablo kümesine koyun. Ancak, veriler hala normalleştirilmelidir, bu da çoklu tablolar gerektirir (ancak iyi dizinlerle).

Diğerlerinin de belirttiği gibi, tetikleyiciler kullanmayın, gruplar halinde senkronize edin.

Çok sayıda birleştirme konusunda endişelenmeyin, veriler düzgün bir şekilde normalleştirildiğinde ve endekslendiğinde bunlar önemli bir maliyet veya yönetim yükü eklemez.

Veri ambarı gibi bir şeye denormalize olmanın zamanı, tahmin edemeyeceğiniz veriler üzerinde birçok farklı türde sorgu yapabilmeniz gerektiğidir. Kendi dezavantajları ve genel giderleri vardır ve uygun olan yerlerde kullanılmalıdır.


3

Geçmişte 7 gün 24 saat imalat yapan bir şirkette buna benzer bir durumla çalıştım ve sonunda işlemsel çoğaltma kullanmaya karar verdim. DDL'nin çoğaltılacak şekilde yapılandırılması mümkündür , böylece yamalar abone için ne değiştirirse gönderilsin. Açıkçası her şeyin artıları ve eksileri vardır ve şirket için en iyi olana karşı neleri destekleyebileceğinizi belirlemek için onları tartmanız gerekir.

Olumlu tarafta:

  1. "Gerçek zamanlı" yalnızca abone üzerindeki ağ ve işlem taahhüdü performansı ile sınırlıdır. Orta derecede yüksek TPS sistemi ile yaşadığım deneyime göre, "gerçek zamanlı" verilerin 10 saniyeden daha kısa bir sürede tekrarlandık.
  2. İş yüklerinin ayrılması. Şu anda bir sunucuda karışık bir iş yükü çalıştırıyorsunuz. Bu iki endişeyi ayırabilirseniz, denklemden bir iş yükünü kaldırmış olmanın her iki sisteminde de performans avantajlarından yararlanabilirsiniz.
  3. Kontrol. Raporlama iş yükünüze uyacak şekilde endeksleme / istatistik / bakım değişiklikleri yapabilirsiniz.

Olumsuz yönleri olsa da:

  1. Maliyet. Başka bir lisans ve daha fazla donanım (sanal veya başka türlü).
  2. Çoğaltma. Düzgün bir şekilde kurulduktan sonra harika çalışıyor, ancak o noktaya ulaşmak bir güçlük olabilir.
  3. Bakım. Yapılarda zararlı değişiklikler yaparsanız (örn. Bir dizin bırakın), anlık görüntü uygulandığında (yayın değiştikten veya makaleler değiştikten sonra) geri döner.

2

Planım, tüm bu kayıtları bir "tümünü yakala" tablosuna yazmak ve bu toplu tabloda kayıtları korumak için orijinal tablolara tetikleyiciler yazmaktı.

Tetikleyicilerin onlardan kaçınmanız gereken birçok sorunu vardır:

  • Tetikleyicideki bir hata, orijinal işlemin iptal edilmesine neden olabilir
  • Çok sıralı işlemleri doğru şekilde işleyen tetikleyicilerin yazılması zordur
  • Tetikleyiciler, döndürülen satır kümesini değiştirerek istemci uygulamalarını karıştırabilir (örneğin, bir tetikleyici etkilenen satırların sayısını geçersiz kılar)
  • Bir tetikleyici diğerini tetiklediğinde, sonuçların tahmin edilmesi zordur

Daha iyi bir seçenek, verileri periyodik olarak yeni bir tabloya kopyalayan bir iştir. Raporlarınız kopyadan çalıştırılabilir. Satırları kopyalayan bir işin yazılması ve bakımı kolaydır ve üçüncü taraf başvurusunun çalışmasını etkileme riski yoktur.


1. Tetikleyiciler basit olacaktır, bu nedenle atılan hatalar hiç olmazsa minimum olacaktır. 2. Tetikleyicinin kendisi birden fazla satırı işlemeyecektir (IE, tetikleyiciyle birlikte tabloda bir satır güncellenmiştir, başka bir yerde birden çok satırın güncellenmesine neden olmaz), ancak kaynakta aynı anda birden çok satır eklenebilir / güncellenebilir / silinebilir tablo - demek istediğin bu mu? 3. bununla başa çıkamaz NOCOUNTmıydı? 4. Hedef tabloda herhangi bir tetikleyici olmazdı ve diğerleri için de aynısını sağlayabilirim.
jreed121

Dediğiniz gibi, tetikleyicilerin çalışması için teorik olarak mümkündür. Sadece pratikte asla yapmazlar.
Andomar
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.