Mengapa Bukankah SQL Lebih Dapat Dihidupkan Kembali? [Tutup]


39

Semua orang tahu bahwa pengembang baru menulis fungsi yang panjang. Ketika Anda maju, Anda menjadi lebih baik dalam memecahkan kode Anda menjadi potongan-potongan kecil dan pengalaman mengajarkan Anda nilai melakukannya.

Masukkan SQL. Ya, cara berpikir SQL tentang kode berbeda dengan cara berpikir prosedural tentang kode, tetapi prinsip ini tampaknya sama berlaku.

Katakanlah saya memiliki kueri yang berbentuk:

select * from subQuery1 inner join subQuerry2 left join subquerry3 left join join subQuery4 

Menggunakan beberapa ID atau tanggal dll.

Subquery itu sendiri kompleks dan mungkin berisi subquery sendiri. Dalam konteks pemrograman lain saya tidak akan berpikir bahwa logika untuk subqueries 1-4 kompleks sesuai dengan permintaan orang tua saya yang bergabung dengan mereka semua. Tampaknya sangat mudah bahwa subqueries tersebut harus didefinisikan sebagai view, sama seperti mereka akan berfungsi jika saya menulis kode prosedural.

Jadi mengapa bukan praktik yang biasa? Mengapa orang begitu sering menulis query SQL monolitik panjang ini? Mengapa SQL tidak mendorong penggunaan tampilan yang luas seperti pemrograman prosedural mendorong penggunaan fungsi yang luas. (Dalam banyak lingkungan perusahaan, membuat tampilan bahkan bukan sesuatu yang mudah dilakukan. Ada permintaan dan persetujuan yang diperlukan. Bayangkan jika jenis programmer lain harus mengirimkan permintaan setiap kali mereka membuat fungsi!)

Saya telah memikirkan tiga kemungkinan jawaban:

  1. Ini sudah umum dan saya bekerja dengan orang yang tidak berpengalaman

  2. Pemrogram berpengalaman tidak menulis SQL kompleks karena mereka lebih suka menyelesaikan masalah pemrosesan data dengan kode prosedural

  3. Sesuatu yang lain


12
Ada organisasi yang hanya mengizinkan Anda melakukan query database melalui tampilan dan memodifikasinya melalui prosedur tersimpan.
Pieter B

3
SQL menjadi jauh lebih menyenangkan bagi saya ketika saya akhirnya menerima bahwa itu tidak akan pernah KERING seperti kode prosedural normal saya.
Graham

1
4. SQL sudah sangat tua dan belum diperbarui secara material dalam beberapa dekade. Untuk hal-hal yang sangat rumit, banyak tim memilih prosedur tersimpan. Anda dapat menambahkan klausa yang berbeda untuk itu. Terkadang Anda hanya perlu menjalankan pekerjaan untuk menampilkan data dalam tabel temp dan kemudian bergabung. Lihatlah betapa berbedanya bahasa deklaratif dan prosedural.
Berin Loritsch

8
Juga salah satu alasannya adalah bahwa ada masalah kinerja yang mengerikan yang disebut "gabungan segitiga" yang dapat terjadi ketika Anda menggunakan tampilan (tentu saja secara tidak sengaja). Jika kueri Anda bergabung dengan Tampilan A dan Lihat B, tetapi Lihat A juga dalam penerapannya menggunakan kembali B, Anda mulai melihat masalah itu. Jadi orang-orang sering memulai dengan menulis satu permintaan monolitik untuk dapat melihat apa yang benar-benar berfungsi terbaik dalam hal refactoring terhadap pandangan, dan kemudian tenggat waktu mereka tercapai, dan monolith masuk ke produksi. Jenis suka 98% dari semua pengembang perangkat lunak, benar-benar :) :)
Stephen Byrne

3
"Bayangkan jika jenis programer lain harus mengirimkan permintaan setiap kali mereka membuat fungsi" ... umm. Anda tidak melakukan review kode?
svidgen

Jawaban:


25

Saya pikir masalah utamanya adalah tidak semua database mendukung Common Table Expressions.

Majikan saya menggunakan DB / 2 untuk banyak hal. Versi terbaru mendukung CTE, sehingga saya dapat melakukan hal-hal seperti:

with custs as (
    select acct# as accountNumber, cfname as firstName, clname as lastName,
    from wrdCsts
    where -- various criteria
)
, accounts as (
    select acct# as accountNumber, crBal as currentBalance
    from crzyAcctTbl
)
select firstName, lastName, currentBalance
from custs
inner join accounts on custs.accountNumber = accounts.accountNumber

Hasilnya adalah bahwa kita dapat memiliki nama tabel / bidang yang sangat singkat dan pada dasarnya saya membuat tampilan temp, dengan nama yang lebih mudah dibaca, yang kemudian dapat saya gunakan. Tentu, kueri menjadi lebih lama. Tetapi hasilnya adalah saya bisa menulis sesuatu yang cukup jelas dipisahkan (menggunakan CTE seperti cara Anda menggunakan fungsi untuk mendapatkan KERING) dan berakhir dengan kode yang cukup terbaca. Dan karena saya dapat memecahkan subquery saya, dan memiliki satu referensi subquery lainnya, itu tidak semua "inline." Kadang-kadang saya telah menulis satu CTE, kemudian meminta empat CTE lain untuk semua referensi, lalu meminta kueri gabungan hasil dari empat terakhir.

Ini dapat dilakukan dengan:

  • DB / 2
  • PostGreSQL
  • Peramal
  • MS SQL Server
  • MySQL (versi terbaru; masih agak baru)
  • mungkin yang lain

Tapi berjalan jauh untuk membuat kode lebih bersih, lebih terbaca, lebih KERING.

Saya telah mengembangkan "pustaka standar" CTE yang dapat saya plug-in ke berbagai pertanyaan, membuat saya memulai dengan memulai permintaan baru saya. Beberapa dari mereka juga mulai dipeluk oleh para dev di organisasi saya.

Pada waktunya, mungkin masuk akal untuk mengubah beberapa dari ini menjadi pandangan, sehingga "pustaka standar" ini tersedia tanpa perlu menyalin / menempel. Tapi CTE saya akhirnya menjadi tweak, sedikit sekali, untuk berbagai kebutuhan yang saya tidak bisa memiliki CTE tunggal biasakan SO WIDELY, tanpa mod, yang mungkin layak membuat tampilan.

Tampaknya bagian dari keluhan Anda adalah "mengapa saya tidak tahu tentang CTE?" atau "mengapa DB saya tidak mendukung CTE?"

Adapun pembaruan ... ya, Anda dapat menggunakan CTE tetapi, dalam pengalaman saya, Anda harus menggunakannya di dalam klausa yang ditetapkan DAN di klausa mana. Akan lebih baik jika Anda bisa mendefinisikan satu atau lebih di depan seluruh pernyataan pembaruan dan kemudian hanya memiliki bagian "permintaan utama" di klausa set / di mana tetapi tidak berfungsi seperti itu. Dan tidak ada menghindari nama tabel / bidang tidak jelas pada tabel yang Anda perbarui.

Anda dapat menggunakan CTE untuk menghapus. Diperlukan beberapa CTE untuk menentukan nilai PK / FK untuk catatan yang ingin Anda hapus dari tabel itu. Sekali lagi, Anda tidak bisa menghindari nama tabel / bidang yang tidak jelas pada tabel yang Anda modifikasi.

Karena Anda dapat memilih ke dalam sisipan, Anda dapat menggunakan CTE untuk memasukkan. Seperti biasa, Anda mungkin berurusan dengan nama tabel / bidang tidak jelas pada tabel yang Anda modifikasi.

SQL TIDAK memungkinkan Anda membuat objek domain yang setara, membungkus tabel, dengan getter / setter. Untuk itu, Anda perlu menggunakan semacam ORM, bersama dengan bahasa pemrograman yang lebih prosedural / OO. Saya sudah menulis hal-hal semacam ini di Java / Hibernate.


4
Kami meminta Tn. Big CTE menjadi orang yang menulis SQL terburuk. Masalahnya adalah CTE adalah pilihan abstraksi yang buruk dan pengoptimal tidak dapat membatalkan setiap algoritma yang Anda masukkan.
Joshua

3
ORM juga dapat melakukan hal-hal yang cukup keji dari segi kinerja, juga ... terutama ketika Anda hanya menggunakan getter dan setter untuk mengambil banyak data. Hibernate terkenal karena menggunakan ratusan kueri individual, bukan satu kueri gabungan yang besar, yang merupakan masalah ketika ada overhead pada setiap kueri.
user3067860

2
@ Yosua Anda dapat menulis kode buruk dalam bahasa apa pun. Termasuk SQL. Tetapi refactoring ke CTE, dilakukan dengan benar, dapat membuat desain bottom-up yang lebih mudah bagi manusia untuk diurai. Saya cenderung melihat itu sebagai sifat yang diinginkan, terlepas dari bahasa apa yang saya hadapi :-)
Meower68

2
Jawaban lainnya bagus, tetapi ini yang saya cari secara pribadi. 'Mengapa saya tidak tahu tentang CTE' adalah sebagian besar masalah saya.
Oebrts

2
@ Meower68 Apakah tidak ada risiko bahwa penggunaan CTE yang ekstensif membuat orang berhenti belajar bergabung dengan benar dan belajar tentang desain basis data yang baik? Saya mendukung nilai CTE tetapi juga membuatnya mudah bekerja dengan subqueries, di mana Anda seharusnya tidak.
Pieter B

36

Mengunci penciptaan tampilan database sering dilakukan oleh organisasi paranoid dari masalah kinerja dalam database. Ini adalah masalah budaya organisasi, bukan masalah teknis dengan SQL.

Lebih dari itu, query SQL monolitik besar ditulis berkali-kali, karena use case sangat spesifik sehingga sangat sedikit kode SQL yang dapat digunakan kembali dalam query lain. Jika permintaan yang kompleks diperlukan, biasanya untuk kasus penggunaan yang jauh berbeda. Menyalin SQL dari kueri lain sering kali merupakan titik awal, tetapi karena sub kueri dan GABUNGAN lain dalam kueri baru, Anda akhirnya memodifikasi SQL yang disalin cukup untuk memecahkan segala jenis abstraksi yang "fungsi" dalam bahasa lain akan lakukan. digunakan untuk. Yang membawa saya ke alasan paling penting mengapa SQL sulit untuk diperbaiki.

SQL hanya berurusan dengan struktur data konkret, bukan perilaku abstrak (atau abstraksi dalam arti kata). Karena SQL ditulis berdasarkan ide-ide konkret, tidak ada yang bisa diabstraksi menjadi modul yang dapat digunakan kembali. Tampilan database dapat membantu dengan ini, tetapi tidak pada tingkat yang sama dengan "fungsi" dalam bahasa lain. Tampilan basis data bukanlah abstraksi, melainkan kueri. Sebenarnya, tampilan basis data adalah kueri. Ini pada dasarnya digunakan seperti tabel, tetapi dieksekusi seperti sub kueri, jadi sekali lagi, Anda berurusan dengan sesuatu yang konkret, bukan abstrak.

Dengan abstraksi, kode menjadi lebih mudah direvisi, karena abstraksi menyembunyikan detail implementasi dari pengguna abstraksi itu. Straight SQL tidak memberikan pemisahan seperti itu, meskipun ekstensi prosedural ke SQL seperti PL / SQL untuk Oracle atau Transact-SQL untuk SQL Server mulai mengaburkan garis sedikit.


"SQL hanya berurusan dengan struktur data konkret, bukan perilaku abstrak (atau abstraksi dalam arti kata)." Ini adalah pernyataan yang aneh, karena dari sudut pandang saya, SQL menangani sepenuhnya perilaku abstrak dan bukan pemrograman konkret dalam arti kata apa pun! Pertimbangkan saja semua tingkat kerumitan besar yang disarikan ke dalam kata sederhana "BERGABUNG": Anda mengatakan Anda ingin hasil yang digabungkan diambil dari dua set data yang berbeda, dan serahkan pada DBMS untuk menentukan teknik konkret yang terlibat, berurusan dengan pengindeksan, menangani perbedaan antara tabel dan subqueries, dll ...
Mason Wheeler

5
@MasonWheeler: Saya kira saya lebih memikirkan SQL dari sudut pandang data kerjanya, bukan implementasi fitur bahasa. Tabel dalam database tidak tampak seperti abstraksi. Mereka konkret, seperti dalam tabel yang disebut "nomor telepon" berisi nomor telepon. Nomor telepon bukan konsep abstrak.
Greg Burghardt

12

Hal yang saya pikir Anda mungkin hilang dari pertanyaan / sudut pandang Anda adalah bahwa SQL menjalankan operasi pada set (menggunakan operasi set dll.).

Ketika Anda beroperasi pada level itu, Anda tentu saja menyerahkan kontrol tertentu ke mesin. Anda masih dapat memaksakan beberapa kode gaya prosedural menggunakan kursor tetapi karena pengalaman menunjukkan 99/100 kali Anda seharusnya tidak melakukannya.

SQL Refactoring dimungkinkan tetapi tidak menggunakan prinsip kode refactoring yang sama seperti yang biasa kita gunakan dalam kode level aplikasi. Sebaliknya Anda mengoptimalkan cara Anda menggunakan mesin SQL itu sendiri.

Ini bisa dilakukan dengan berbagai cara. Jika Anda menggunakan Microsoft SQL Server, Anda dapat menggunakan SSMS untuk memberi Anda perkiraan rencana eksekusi dan Anda bisa menggunakannya untuk melihat langkah-langkah yang dapat Anda lakukan untuk menyempurnakan kode Anda.

Dalam kasus pemisahan kode menjadi modul-modul yang lebih kecil, seperti yang disebutkan @ greg-burghardt, SQL umumnya merupakan bagian kode yang dibuat khusus dan sebagai hasilnya. Itu melakukan satu hal yang perlu Anda lakukan dan tidak ada lagi. Itu mematuhi S dalam SOLID, hanya ada satu alasan untuk diubah / terpengaruh dan saat itulah Anda memerlukan permintaan itu untuk melakukan sesuatu yang lain. Sisa dari akronim (OLID) tidak berlaku di sini (AFAIK tidak ada injeksi dependensi, antarmuka atau dependensi seperti itu dalam SQL) tergantung pada rasa SQL yang Anda gunakan, Anda mungkin dapat memperluas pertanyaan tertentu dengan membungkusnya dalam fungsi prosedur / tabel tersimpan atau menggunakannya sebagai sub-kueri jadi, saya akan mengatakan prinsip buka-tutup akan tetap berlaku. Tapi saya ngelantur.

Saya pikir Anda perlu mengubah paradigma Anda dalam hal bagaimana Anda melihat kode SQL. Karena sifat set itu tidak dapat menyediakan banyak fitur yang dapat bahasa tingkat aplikasi (generik dll). SQL tidak pernah dirancang untuk menjadi seperti itu, itu adalah bahasa untuk permintaan set data, dan setiap set unik dengan caranya sendiri.

Yang sedang berkata, ada cara di mana Anda dapat membuat kode Anda terlihat lebih bagus, jika keterbacaan adalah prioritas tinggi dalam organisasi. Menyimpan bit dari blok SQL yang sering digunakan (kumpulan data umum yang Anda gunakan) ke fungsi nilai prosedur / tabel yang disimpan dan kemudian meminta dan menyimpannya dalam variabel tabel / tabel sementara, diikuti dengan menggunakannya untuk menggabungkan potongan-potongan tersebut menjadi satu transaksi besar. yang seharusnya Anda tulis adalah pilihan. IMHO tidak layak melakukan sesuatu seperti itu dengan SQL.

Sebagai bahasa itu dirancang agar mudah dibaca dan dimengerti oleh siapa pun, bahkan non-programmer. Dengan demikian, kecuali jika Anda melakukan sesuatu yang sangat pintar, tidak perlu mengubah kode SQL menjadi ukuran byte yang lebih kecil. Saya, secara pribadi, telah menulis query SQL yang sangat besar saat mengerjakan solusi data warehouse ETL / Reporting dan semuanya masih sangat jelas dalam hal apa yang sedang terjadi. Apa pun yang mungkin terlihat agak aneh bagi orang lain akan mendapatkan satu set komentar singkat di sampingnya untuk memberikan penjelasan singkat.

Saya harap ini membantu.


6

Saya akan fokus pada "subqueries" dalam contoh Anda.

Mengapa mereka begitu sering digunakan? Karena mereka menggunakan cara berpikir alami seseorang: Saya memiliki set data ini, dan ingin melakukan suatu tindakan pada subsetnya dan bergabung dengan subset data lainnya. 9 dari 10 kali saya melihat subquery, itu digunakan salah. Lelucon saya tentang subqueries adalah: orang yang takut bergabung menggunakan subqueries.

Jika Anda melihat subquery seperti itu, itu juga sering merupakan tanda desain database yang tidak optimal.

Semakin Normalisasi Basis Data Anda, semakin banyak yang Anda dapatkan, semakin banyak basis data Anda yang tampak seperti lembar excel besar, semakin banyak sub-pilihan yang Anda dapatkan.

Refactoring dalam SQL seringkali dengan tujuan yang berbeda: mendapatkan lebih banyak kinerja, waktu kueri yang lebih baik, "menghindari pemindaian tabel". Mereka bahkan dapat membuat kode kurang dibaca tetapi sangat berharga.

Jadi mengapa Anda melihat begitu banyak pertanyaan monolitik besar non-refactored?

  • SQL, dalam banyak hal bukan bahasa pemrograman.
  • Desain basis data buruk.
  • Orang-orang tidak benar-benar fasih dalam SQL.
  • Tidak ada kekuatan atas database (misalnya tidak diizinkan menggunakan tampilan)
  • Tujuan berbeda dengan refactoring.

(Bagi saya, semakin saya berpengalaman dengan SQL, semakin sedikit pertanyaan saya, SQL memiliki cara untuk orang-orang dari semua tingkat keterampilan untuk menyelesaikan pekerjaan mereka, apa pun yang terjadi.)


6
"Subqueries" juga merupakan agregasi dari db yang dinormalisasi dengan semestinya sebagaimana akan menjadi normalisasi ad-hoc dari db yang tidak dinormalisasi
Caleth

@ Caleth itu benar sekali.
Pieter B

5
Bahkan dalam database yang dinormalisasi dengan baik, masih sering diperlukan untuk bergabung dengan subqueries, daripada bergabung langsung dengan tabel. Misalnya jika Anda perlu bergabung dengan data yang dikelompokkan.
Barmar

1
@Barmar pasti, maka 9 dari 10 komentar saya Sub-kueri memiliki tempat mereka tetapi saya melihat mereka terlalu sering digunakan oleh orang-orang yang tidak berpengalaman.
Pieter B

Saya suka metrik Anda "jumlah subqueries" sebagai indikasi normalisasi basis data (atau ketiadaan).
Jason

2

Pemisahan tugas

Dalam semangat SQL, database adalah aset bersama yang berisi data perusahaan, dan melindunginya sangat penting. Memasuki DBA sebagai penjaga kuil.

Membuat tampilan baru dalam database dipahami untuk melayani tujuan yang langgeng dan untuk dibagikan oleh komunitas pengguna. Dalam tampilan DBA, ini hanya dapat diterima jika tampilan dibenarkan oleh struktur data. Setiap perubahan tampilan kemudian dikaitkan dengan risiko untuk semua pengguna saat ini, bahkan mereka yang tidak menggunakan aplikasi tetapi yang telah menemukan tampilan. Akhirnya, pembuatan objek baru memerlukan otorisasi kelola, dan dalam kasus tampilan, secara konsisten dengan otorisasi tabel yang mendasarinya.

Semua ini menjelaskan mengapa DBA tidak suka menambahkan tampilan yang hanya untuk kode beberapa aplikasi individual.

Desain SQL

Jika Anda menguraikan salah satu kueri rumit yang bagus, Anda mungkin menemukan bahwa subquery akan sering memerlukan parameter yang bergantung pada subquery lain.

Jadi mentransformasikan subqueries dalam pandangan tidak harus sesederhana yang dinyatakan. Anda harus mengisolasi parameter variabel, dan merancang tampilan Anda sehingga parameter dapat ditambahkan sebagai kriteria pemilihan pada tampilan.

Sayangnya, saat melakukannya, Anda terkadang memaksakan untuk mengakses lebih banyak data dan kurang efektif daripada dalam kueri khusus.

Ekstensi kepemilikan

Anda bisa berharap beberapa refactoring, dengan mentransfer beberapa tanggung jawab ke ekstensi prosedural dari SQL, seperti PL / SQL atau T-SQL. Namun, ini tergantung vendor dan membuat ketergantungan teknologi. Selain itu, ekstensi ini dijalankan pada server database, menciptakan lebih banyak beban pemrosesan pada sumber daya yang jauh lebih sulit untuk diukur daripada server aplikasi.

Tapi apa masalahnya pada akhirnya?

Akhirnya, apakah pemisahan tugas dan desain SQL dengan kekuatan dan keterbatasannya merupakan masalah nyata? Pada akhirnya, basis data ini terbukti berhasil dan andal menangani data yang sangat kritis termasuk dalam lingkungan kritis misi.

Jadi untuk mencapai refactoring yang sukses:

  • pertimbangkan komunikasi yang lebih baik . Cobalah untuk memahami kendala DBA Anda. Jika Anda membuktikan kepada DBA bahwa pandangan baru dibenarkan oleh struktur data, bahwa itu bukan solusi membuang-pergi, dan bahwa itu tidak memiliki dampak keamanan, dia pasti akan setuju untuk membiarkannya dibuat. Karena, maka itu akan menjadi kepentingan bersama.

  • bersihkan rumah Anda sendiri terlebih dahulu : Tidak ada yang memaksa Anda untuk menghasilkan banyak SQL di banyak tempat. Perbaiki kode aplikasi Anda, untuk mengisolasi akses SQL, dan untuk membuat kelas atau fungsi untuk menyediakan subqueries yang dapat digunakan kembali, jika ini sering digunakan.

  • tingkatkan kesadaran tim : pastikan aplikasi Anda tidak melakukan tugas yang dapat dilakukan dengan lebih efisien oleh mesin DBMS. Seperti yang Anda tunjukkan dengan benar, pendekatan prosedural dan pendekatan berorientasi data tidak sama dikuasainya oleh anggota tim yang berbeda. Itu tergantung pada latar belakang mereka. Tetapi untuk mengoptimalkan sistem secara keseluruhan, tim Anda perlu memahaminya secara keseluruhan. Jadi ciptakan kesadaran, jadi untuk memastikan bahwa pemain yang kurang berpengalaman tidak menemukan kembali roda dan membagikan pemikiran DB mereka dengan anggota yang lebih berpengalaman.


+1 Beberapa poin bagus di sini. Mengingat betapa buruknya beberapa SQL, sikap diam dari DBA untuk memungkinkan pandangan sering sepenuhnya dimengerti. Juga, SQL pasti bisa mendapat manfaat dari peer review jika sumber daya haus dan / atau itu akan sering dijalankan.
Robbie Dee

1

Poin 1 & 3: Tampilan bukan satu-satunya cara. Ada juga tabel sementara, mart, variabel tabel, kolom teragregasi, CTE, fungsi, prosedur tersimpan dan kemungkinan konstruksi lainnya tergantung pada RDBMS.

DBA (dan saya berbicara sebagai seseorang yang telah menjadi DBA dan pengembang) cenderung memandang dunia dengan cara yang sangat biner sehingga seringkali menentang hal-hal seperti pandangan dan fungsi karena penalti kinerja yang dirasakan.

Akhir-akhir ini, kebutuhan untuk bergabung kompleks telah berkurang dengan pengakuan bahwa tabel yang dinormalisasi meskipun sub-optimal dari sudut pandang NF , sangat berkinerja tinggi.

Ada juga tren untuk melakukan kueri sisi klien dengan teknologi seperti LINQ yang Anda tingkatkan di poin 2.

Sementara saya setuju bahwa SQL dapat menantang untuk modularise, langkah besar telah dibuat walaupun akan selalu ada dikotomi antara kode sisi klien dan SQL - meskipun 4GL telah mengaburkan garis.

Saya kira itu benar-benar tergantung pada seberapa jauh DBA / arsitek / lead teknologi Anda bersedia untuk menyerah dalam hal ini. Jika mereka menolak untuk mengizinkan apa pun selain vanilla SQL dengan banyak gabungan, pertanyaan besar dapat terjadi. Jika Anda terjebak dengan ini, jangan membenturkan kepala Anda ke dinding bata, tingkatkan itu. Biasanya ada cara yang lebih baik dalam melakukan sesuatu dengan sedikit kompromi - terutama jika Anda dapat membuktikan manfaatnya.


1
Saya belum pernah mendengar tentang konstruksi "mart". Apa itu?
Uskup

1
Mart hanya sebagian dari repositori (master database). Jika ada permintaan kompleks spesifik yang perlu dijalankan, database khusus dapat dibuat khusus untuk melayani permintaan tersebut. Contoh yang sangat umum adalah mart pelaporan.
Robbie Dee

1
Bingung mengapa ini diturunkan. Tidak langsung menjawab pertanyaan, tetapi memberikan jawaban implisit yang cukup jelas dari "opsi 3: ada banyak cara untuk menangani ini, yang banyak digunakan".
Dewi Morgan

TIL tentang data mart. Punya +1!
Uskup
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.