Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

Dasar-dasar ekspresi tabel, Bagian 1

Artikel ini adalah yang pertama dalam seri tentang dasar-dasar ekspresi tabel di T-SQL. Saya terutama akan fokus pada empat jenis ekspresi tabel bernama, yang dikenal di T-SQL sebagai tabel turunan, ekspresi tabel umum (CTE), tampilan, dan fungsi bernilai tabel sebaris (TVF inline).

Saya terinspirasi untuk menulis seri ini oleh teman baik saya, Grant Fritchey, yang telah saya kenal selama bertahun-tahun. Seperti yang berulang kali ditunjukkan oleh Grant, banyak yang menggunakan ekspresi tabel umum di T-SQL berpikir bahwa SQL Server mempertahankan kumpulan hasil kueri dalam, dan alasan untuk keyakinan ini adalah penggunaan istilah tabel atas nama konstruk. Ketika topik ini muncul dalam diskusi komunitas, seringkali orang berpendapat bahwa penggunaan istilah tabel dalam nama konstruk tidak tepat karena sebenarnya bukan tabel. Bahkan ada saran untuk memulai kampanye penamaan dengan harapan melihat perubahan nama di masa mendatang untuk konstruksi ini, setidaknya di T-SQL. Beberapa saran termasuk ekspresi kueri , tampilan sebaris , tampilan tingkat pernyataan , dan lain-lain.

Mungkin ini akan mengejutkan beberapa orang, tetapi saya benar-benar menemukan penggunaan istilah tabel dalam ekspresi tabel umum sebagai sangat tepat. Bahkan, saya menemukan penggunaan istilah ekspresi tabel sewajarnya. Bagi saya, cara terbaik untuk menjelaskan apa itu CTE di T-SQL, ini adalah ekspresi tabel bernama . Hal yang sama berlaku untuk apa yang disebut T-SQL sebagai tabel turunan (konstruk bahasa khusus yang bertentangan dengan gagasan umum), tampilan, dan TVF sebaris. Mereka semua bernama ekspresi tabel.

Jika Anda bisa bersabar dengan saya sedikit, saya akan memberikan alasan untuk pandangan saya tentang berbagai hal di artikel ini. Terpikir oleh saya bahwa kebingungan penamaan, dan kebingungan seputar apakah ada aspek persistensi pada ekspresi tabel, dapat diselesaikan dengan pemahaman yang lebih baik tentang dasar-dasar bidang sistem manajemen basis data relasional kami. Dasar-dasar itu adalah, teori relasional, bagaimana SQL (bahasa standar) berhubungan dengannya, dan bagaimana dialek T-SQL yang digunakan dalam implementasi SQL Server dan Azure SQL Database berhubungan dengan keduanya.

Sebagai titik awal, Anda ingin dapat menjawab pertanyaan-pertanyaan berikut:

  • Apa yang dimaksud dengan independensi data fisik prinsip dalam model relasional berarti?
  • Apa yang dimaksud dengan tabel dalam SQL dan apa yang menjadi mitra dalam model relasional?
  • Apa sifat penutupan aljabar relasional?
  • Apa itu ekspresi tabel dan apa pasangannya dalam model relasional?

Setelah Anda dapat menjawab pertanyaan di atas dengan benar, kemungkinan besar Anda akan menemukan penggunaan istilah ekspresi tabel bernama sesuai untuk konstruksi yang disebutkan di atas (yang disebut T-SQL sebagai tabel turunan, CTE, tampilan, dan TVF inline).

Saya tidak ingin terdengar seperti saya memiliki pemahaman yang sangat mendalam tentang teori relasional. Keahlian saya adalah T-SQL. Saya mengakui bahwa ada lebih banyak hal yang tidak saya ketahui tentang teori relasional daripada yang saya ketahui, dan bahwa beberapa hal yang saya pikir saya tahu, ternyata tidak demikian. Ketika saya membaca tulisan-tulisan C.J. Dates tentang topik tersebut, saya merasa bahwa saya hampir tidak menggores permukaan dari apa yang perlu diketahui, dan bahwa saya dapat, dan harus, berusaha untuk memahaminya dengan lebih baik. Saya mengakui dan sangat yakin bahwa pemahaman yang baik tentang teori relasional diterjemahkan langsung ke pemahaman yang lebih baik tentang SQL dan T-SQL, dan untuk menulis kode T-SQL yang lebih baik, lebih akurat, dan lebih kuat. Bagi siapa saja yang memilih data sebagai karir mereka, saya sarankan membaca SQL dan Teori Relasional:Cara Menulis Kode SQL yang Akurat Edisi ke-3 oleh C. J. Date (O'Reilly 2015).

Di bagian pertama seri ini, saya ingin membangun pemahaman tentang penggunaan istilah ekspresi tabel dan ekspresi tabel bernama , yang sesuai dengan penggunaan istilah ini oleh Date, dan sayangnya tidak sesuai dengan penggunaan istilah ini oleh Standar SQL. Untuk mencapai hal ini, saya akan memberikan sedikit latar belakang dari teori relasional dan standar SQL. Tapi seperti yang saya katakan, saya merekomendasikan membaca buku Date untuk liputan yang benar-benar mendetail tentang topik ini.

Saya akan mulai dengan menjelaskan apa yang dimaksud dengan prinsip independensi data fisik. Selanjutnya, saya akan menjelaskan apa itu tabel dalam SQL dan tandingannya dalam teori relasional. Saya kemudian akan menjelaskan apa yang dimaksud dengan sifat penutupan aljabar relasional. Setelah Anda memiliki gagasan yang masuk akal tentang apa itu tabel, dan apa arti properti penutupan, menjadi cukup mudah untuk memahami apa itu ekspresi tabel. Fokus saya kemudian akan beralih ke spesifik di T-SQL. Banyak yang ingin saya katakan tentang dasar-dasar ekspresi tabel di T-SQL—baik dalam hal perlakuan konseptual maupun dalam hal detail implementasi, termasuk representasi fisik dan pertimbangan penyetelan kueri.

Saya menemukan topik ini menarik dan sangat praktis setelah Anda mempelajari detail implementasi. Sebenarnya, ada banyak hal yang ingin saya katakan tentangnya sehingga saya tidak yakin berapa banyak bagian dari seri ini pada akhirnya. Apa yang dapat saya katakan kepada Anda dengan tingkat kepercayaan yang tinggi adalah bahwa akan ada banyak bagian. Mungkin lebih dari satu dan kurang dari 100. Di bagian mendatang saya akan mempelajari tipe individu dari ekspresi tabel bernama, pertimbangan modifikasi, aspek inlining, aspek pemesanan, korelasi, dan banyak lagi.

Dalam contoh saya, saya akan menggunakan database sampel yang disebut TSQLV5. Anda dapat menemukan skrip yang membuat dan mengisi database ini di sini, dan diagram ER-nya di sini.

Independensi data fisik

Independensi data fisik adalah prinsip dalam teori relasional yang mengatakan bahwa detail implementasi fisik harus disembunyikan dari, atau transparan kepada, pengguna yang mengirimkan kueri terhadap sistem manajemen basis data relasional. Dalam kueri, pengguna seharusnya fokus pada apa mereka perlu menggunakan operasi logika yang didasarkan pada aljabar relasional, bukan bagaimana untuk mendapatkan datanya. Mereka tidak perlu khawatir tentang bagaimana data terstruktur, diakses, dan diproses. Detail implementasi fisik seperti itu cenderung berbeda secara substansial antara implementasi yang berbeda (produk RDBMS). Bahkan dengan RDBMS yang sama, detail implementasi fisik terkadang berubah di antara versi dan build yang berbeda. Ide di balik prinsip independensi data fisik secara teori adalah untuk melindungi investasi pengguna dengan menghilangkan kebutuhan untuk merevisi solusi Anda saat Anda meningkatkan RDBMS ke versi baru, atau bahkan saat Anda bermigrasi dari satu RDBMS ke RDBMS lainnya. Seperti yang mungkin Anda ketahui dengan baik, dalam praktiknya tidak sesederhana itu, tetapi itu adalah topik untuk diskusi yang berbeda.

Apa itu tabel?

Jika Anda telah bekerja dengan T-SQL atau dialek SQL lainnya untuk sementara waktu, Anda mengembangkan pemahaman intuitif tentang apa itu tabel. Masalahnya adalah bahwa tanpa latar belakang teori relasional, seringkali pemahaman intuitif tidak terlalu akurat. Salah satu kesalahan umum adalah bahwa kita secara intuitif cenderung fokus pada detail implementasi fisik. Misalnya, ketika Anda berpikir tentang apa itu tabel, apakah Anda memikirkan tabel sebagai struktur logis (sekumpulan baris) atau apakah Anda memikirkan detail implementasi fisik di platform yang Anda gunakan (dalam SQL Server , halaman, luasan, tumpukan versus indeks berkerumun, indeks tidak berkerumun, dan sebagainya)? Sebagai pengguna yang menulis kode SQL untuk menanyakan tabel, mengikuti prinsip independensi data fisik, Anda seharusnya menganggap tabel sebagai struktur logis, dan membiarkan RDBMS mengkhawatirkan detail implementasi fisik. Jadi, mari kita mundur selangkah dan mencoba mencari tahu apa itu tabel.

Sebuah tabel adalah rekan SQL untuk struktur utama dalam teori relasional — sebuah relasi. Untuk menjaga hal-hal sederhana dan membatasi cakupan cakupan saya, saya tidak akan membahas perbedaan antara variabel relasi dan nilai relasi. Jika Anda mengikuti rekomendasi saya dan membaca buku Date, Anda akan segera memiliki gambaran yang jelas tentang seluk-beluk tersebut.

Sebuah relasi memiliki heading dan body.

Judul relasi adalah set dari atribut . Dalam teori himpunan matematika, himpunan tidak memiliki urutan dan tidak ada duplikat. Anda seharusnya mengidentifikasi atribut berdasarkan nama dan bukan berdasarkan posisi. Akibatnya, nama atribut harus unik.

Bisakah Anda mengidentifikasi apa yang setara dengan atribut dalam SQL? Anda mungkin menebak bahwa itu adalah kolom . Namun, SQL sebenarnya memiliki gagasan tentang urutan kolomnya berdasarkan urutan kemunculannya dalam pernyataan CREATE TABLE. Misalnya, inilah pernyataan CREATE TABLE untuk tabel Sales.Shippers di database TSQLV5:

CREATE TABLE Sales.Shippers
(
  shipperid   INT          NOT NULL IDENTITY,
  companyname NVARCHAR(40) NOT NULL,
  phone       NVARCHAR(24) NOT NULL,
  CONSTRAINT  PK_Shippers  PRIMARY KEY(shipperid)
);

Buat kueri tabel menggunakan SELECT * . yang terkenal jahat , seperti ini:

SELECT * FROM Sales.Shippers;

Ketika saya menjalankan kueri ini di sistem saya, saya mendapatkan output berikut:

shipperid  companyname    phone
---------- -------------- ---------------
1          Shipper GVSUA  (503) 555-0137
2          Shipper ETYNR  (425) 555-0136
3          Shipper ZHISN  (415) 555-0138

SQL menjamin bahwa kolom akan dikembalikan dari kiri ke kanan berdasarkan urutan definisi. Saya akan menjelaskan apa yang terjadi dengan baris segera. SQL bahkan memungkinkan Anda untuk merujuk ke posisi ordinal kolom dari daftar SELECT dalam klausa ORDER BY, seperti itu (bukan berarti saya merekomendasikan praktik ini, begitu pula Aaron Bertrand):

SELECT shipperid, companyname, phone
FROM Sales.Shippers
ORDER BY 2;

Kueri ini menghasilkan keluaran berikut:

shipperid  companyname    phone
---------- -------------- ---------------
2          Shipper ETYNR  (425) 555-0136
1          Shipper GVSUA  (503) 555-0137
3          Shipper ZHISN  (415) 555-0138

Tubuh suatu relasi adalah sekumpulan tupel . Sekali lagi, ingat bahwa satu set tidak memiliki urutan dan tidak ada duplikat. Oleh karena itu, suatu relasi harus memiliki setidaknya satu kunci kandidat yang memungkinkan Anda untuk mengidentifikasi sebuah tupel secara unik. Mitra SQL untuk tuple adalah baris . Namun, dalam SQL Anda tidak dipaksa untuk menentukan kunci dalam tabel, dan jika tidak, Anda bisa berakhir dengan baris duplikat. Bahkan jika Anda memiliki kunci yang ditentukan di tabel Anda, Anda bisa mendapatkan baris duplikat yang dikembalikan dari kueri terhadap tabel. Ini contohnya:

SELECT country FROM HR.Employees;

Kueri ini menghasilkan keluaran berikut:

country
--------
USA
USA
USA
USA
UK
UK
UK
USA
UK

Kueri ini tidak menghasilkan hasil relasional karena kemungkinan baris duplikat. Sedangkan teori relasional didasarkan pada teori himpunan, SQL didasarkan pada teori multiset. Multiset (alias superset atau tas) dapat memiliki duplikat. SQL memang memberi Anda alat untuk menghilangkan duplikat dengan klausa DISTINCT, seperti:

SELECT DISTINCT country FROM HR.Employees;

Kueri ini menghasilkan keluaran berikut:

country
--------
UK
USA

Apa yang SQL pertahankan dari teori relasional dalam hal tubuh tabel adalah properti no-order. Kecuali Anda menambahkan klausa ORDER BY dalam kueri, Anda tidak memiliki jaminan bahwa hasilnya akan memiliki urutan tertentu di antara baris. Jadi, isi dari hasil query di atas adalah relasional, setidaknya dalam arti tidak memiliki duplikat dan tidak memiliki jaminan urutan.

Misalkan Anda membuat kueri tabel di SQL Server, dan Anda tidak menyertakan klausa ORDER BY dalam kueri. Apakah Anda mengharapkan SQL Server untuk selalu mengembalikan baris dalam urutan tertentu sebagai perilaku yang dijamin? Banyak orang melakukannya. Banyak yang berpikir bahwa Anda akan selalu mendapatkan baris kembali berdasarkan urutan indeks berkerumun. Itu adalah contoh bagus untuk mengabaikan prinsip independensi data fisik, dan membuat asumsi berdasarkan intuisi, dan mungkin berdasarkan perilaku yang diamati di masa lalu. Microsoft tahu bahwa kueri SQL tanpa klausa ORDER BY tidak menjamin urutan apa pun di antara baris hasil, dan karenanya meskipun pada tingkat fisik data berada dalam struktur indeks, SQL Server tidak harus memproses data dalam indeks memesan. Ia dapat memilih, dalam kondisi fisik tertentu, untuk melakukannya, tetapi ia dapat memilih untuk tidak melakukannya dalam kondisi fisik lainnya. Ingat juga bahwa detail implementasi fisik dapat berubah di antara versi dan build produk yang berbeda. Jika Anda ingin menjamin bahwa kueri akan mengembalikan baris hasil dalam beberapa urutan tertentu, satu-satunya cara Anda untuk menjamin ini adalah dengan memasukkan klausa ORDER BY di kueri terluar.

Seperti yang mungkin telah Anda kumpulkan, para perancang SQL tidak benar-benar melihatnya sebagai prioritas untuk mengikuti teori relasional. Dan apa yang saya jelaskan di sini hanyalah beberapa contoh. Ada banyak lagi. Seperti yang disebutkan sebelumnya, tujuan saya dalam artikel ini hanya untuk memberikan latar belakang teoretis kritis yang cukup untuk menghilangkan kebingungan seputar ekspresi tabel, sebelum saya mulai mempelajari secara spesifik dalam T-SQL di artikel mendatang.

Apa itu ekspresi tabel?

Aljabar relasional (aljabar yang mendefinisikan operasi pada hubungan dalam teori relasional) memiliki penutupan Properti. Artinya, operasi pada relasi menghasilkan relasi. Operator relasional beroperasi pada satu atau lebih relasi sebagai input dan menghasilkan relasi tunggal sebagai output. Properti penutupan memungkinkan Anda untuk membuat sarang operasi. Sebuah ekspresi relasional adalah ekspresi yang beroperasi pada relasi dan mengembalikan relasi. Oleh karena itu, ekspresi relasional dapat digunakan di mana aljabar relasional mengharapkan suatu relasi.

Jika Anda memikirkannya, itu tidak berbeda dengan operasi pada bilangan bulat yang menghasilkan hasil bilangan bulat. Misalkan variabel @i adalah variabel integer. Ekspresi @i + 42 menghasilkan bilangan bulat dan oleh karena itu dapat digunakan di mana bilangan bulat diharapkan, seperti pada (@i + 42) * 2.

Mengingat bahwa tabel dalam SQL adalah mitra dari suatu hubungan dalam teori relasional, meskipun tidak terlalu berhasil, ekspresi tabel dalam SQL adalah mitra dari ekspresi relasional. Seperti disebutkan sebelumnya, saya menggunakan istilah ekspresi tabel mengikuti penggunaan istilah ini oleh C.J. Dates. Standar SQL memiliki banyak istilah yang membingungkan, beberapa di antaranya saya khawatir tidak terlalu tepat. Misalnya, SQL Standard menggunakan istilah ekspresi tabel untuk menggambarkan secara spesifik ekspresi berdasarkan klausa kueri yang dimulai dengan klausa FROM wajib, dan termasuk opsional klausa WHERE, GROUP BY, HAVING dan WINDOW (yang terakhir tidak didukung di T -SQL), dan mengecualikan klausa SELECT. Berikut spesifikasi standarnya:

7.4

Fungsi
Menentukan tabel atau tabel yang dikelompokkan.

Format
::=

[ ]
[ ]
[ ]
[ ]

Memang benar bahwa hasil dari apa yang disebut standar sebagai ekspresi tabel dianggap sebagai tabel, tetapi Anda tidak dapat menggunakan ekspresi seperti itu sebagai kueri yang berdiri sendiri. Versi tanggal dari ekspresi tabel istilah sebenarnya lebih dekat dengan apa yang disebut standar SQL ekspresi kueri . Berikut spesifikasi standar untuk apa yang disebut ekspresi kueri:

7.17

Fungsi
Menentukan tabel.

Format
::=
[ ]
[ ] [ ] [ ]
::=
WITH [ RECURSIVE ]
::=
[ { }… ]
::=
[ ]
SEBAGAI [ ]
::=

::=

| UNION [ SEMUA | BERBEDA ]
[ ]
| KECUALI [ SEMUA | BERBEDA ]
[ ]
::=

| INTERSECT [ SEMUA | BERBEDA ]
[ ]
::=

|
[ ] [ ] [ ]

::=

|
|
::=
TABEL
::=
SESUAI [ OLEH ]
::=

::=
ORDER BY
::=
OFFSET { ROW | BARIS }
::=
FETCH { PERTAMA | BERIKUTNYA } [ ] { BARIS | BARIS } { HANYA | WITH TIES }
::=

|
::=

::=

::=
PERCENT

7.3

Fungsi
Menentukan sekumpulan s yang akan dibuat menjadi sebuah tabel.

Format
::=
NILAI
::=
[ { }… ]
::=
VALUES
::=

[ { }… ]

Perhatikan bahwa spesifikasi ini mencakup apa yang disebut T-SQL sebagai ekspresi tabel umum, meskipun standar tidak benar-benar menggunakan istilah ini, melainkan hanya menyebutnya dengan elemen daftar . Perhatikan juga bahwa apa yang disebut ekspresi kueri tidak harus didasarkan pada kueri, melainkan dapat didasarkan pada apa yang disebut konstruktor nilai tabel (penggunaan klausa VALUES untuk membuat sekumpulan baris). Terakhir, meskipun ekspresi kueri standar didasarkan pada ekspresi, ia mengembalikan tabel, dan dapat digunakan di tempat yang biasanya diharapkan. Untuk alasan ini, saya menemukan penggunaan Date dari istilah ekspresi tabel jauh lebih tepat.

Kesimpulan

Saya dapat melihat mengapa beberapa orang mungkin menganggap tempat tinggal pada penamaan dan terminologi sebagai sedikit bertele-tele dan bahkan mungkin membuang-buang waktu. Saya merasa sangat berbeda, meskipun. Saya percaya bahwa dalam bidang apa pun, aspirasi untuk menggunakan nama dan istilah yang tepat memaksa Anda untuk mempelajari dasar-dasarnya dengan baik, dan mencerminkan pengetahuan Anda. Semoga dalam artikel ini saya tidak cukup berhasil mengasingkan Anda untuk tidak ingin melanjutkan ke bagian-bagian berikutnya dalam seri, mulai dengan artikel bulan depan, saya akan mengalihkan fokus saya ke cara berbagai jenis penamaan. ekspresi tabel ditangani menggunakan T-SQL di SQL Server dan Azure SQL Database.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ubah Data ODBC di CloverDX

  2. Langsung ke Memulai Pengembangan Basis Data Berbasis Tes (TDDD)

  3. IGNORE_DUP_KEY lebih lambat pada indeks berkerumun

  4. Model Basis Data untuk Platform MOOC

  5. Model Data Aplikasi Pelatihan Marathon