Bagikan melalui


Pemodelan data di Azure Cosmos DB untuk NoSQL

Meskipun database bebas skema, seperti Azure Cosmos DB, memudahkan untuk menyimpan dan mengkueri data yang tidak terstruktur dan semi terstruktur, pikirkan model data Anda untuk mengoptimalkan performa, skalabilitas, dan biaya.

Bagaimana data disimpan? Bagaimana aplikasi Anda mengambil dan mengkueri data? Apakah aplikasi Anda baca-berat atau tulis-berat?

Setelah membaca artikel ini, Anda dapat menjawab pertanyaan berikut:

  • Apa itu pemodelan data dan mengapa saya harus peduli?
  • Bagaimana pemodelan data di Azure Cosmos DB berbeda dari database relasional?
  • Bagaimana Anda mengekspresikan hubungan data dalam database nonrelasi?
  • Kapan saya menyematkan data dan kapan saya menautkan ke data?

Nomor dalam format JSON

Azure Cosmos DB menyimpan dokumen di JSON, jadi penting untuk menentukan apakah akan mengonversi angka menjadi string sebelum menyimpannya di JSON. Konversikan semua angka menjadi String jika mungkin melebihi batas angka presisi ganda seperti yang didefinisikan oleh Institute of Electrical and Electronics Engineers (IEEE) 754 binary64. Spesifikasi JSON menjelaskan mengapa menggunakan angka di luar batas ini adalah praktik yang buruk karena masalah interoperabilitas. Kekhawatiran ini sangat relevan untuk kolom kunci partisi karena tidak dapat diubah dan memerlukan migrasi data untuk berubah nanti.

Menyematkan data

Saat Anda memodelkan data di Azure Cosmos DB, perlakukan entitas Anda sebagai item mandiri yang diwakili sebagai dokumen JSON.

Sebagai perbandingan, mari kita lihat terlebih dahulu bagaimana kita dapat memodelkan data dalam database relasional. Contoh berikut memperlihatkan bagaimana seseorang mungkin disimpan dalam database relasional.

Cuplikan layar model database relasional.

Saat bekerja dengan database relasional, strateginya adalah menormalkan semua data Anda. Menormalkan data Anda biasanya melibatkan pengambilan entitas, seperti seseorang, dan memecahnya menjadi komponen diskrit. Dalam contoh, seseorang mungkin memiliki beberapa catatan detail kontak, dan beberapa rekaman alamat. Anda dapat merinci detail kontak lebih lanjut dengan mengekstrak bidang umum seperti jenis. Pendekatan yang sama berlaku untuk alamat. Setiap rekaman dapat diklasifikasikan sebagai Rumah atau Bisnis.

Panduan lokal saat menormalkan data adalah untuk menghindari penyimpanan data redundan di setiap rekaman dan sebagai gantinya merujuk ke data. Dalam contoh ini, untuk membaca seseorang, dengan semua detail dan alamat kontak mereka, Anda perlu menggunakan JOINS untuk secara efektif menyusun kembali (atau mendenormalisasi) data Anda pada waktu proses.

SELECT p.FirstName, p.LastName, a.City, cd.Detail
FROM Person p
JOIN ContactDetail cd ON cd.PersonId = p.Id
JOIN ContactDetailType cdt ON cdt.Id = cd.TypeId
JOIN Address a ON a.PersonId = p.Id

Memperbarui detail dan alamat kontak satu orang memerlukan operasi tulis di banyak tabel individual.

Sekarang mari kita lihat bagaimana kita akan memodelkan data yang sama dengan entitas mandiri di Azure Cosmos DB.

{
    "id": "1",
    "firstName": "Thomas",
    "lastName": "Andersen",
    "addresses": [
        {
            "line1": "100 Some Street",
            "line2": "Unit 1",
            "city": "Seattle",
            "state": "WA",
            "zip": 98012
        }
    ],
    "contactDetails": [
        {"email": "thomas@andersen.com"},
        {"phone": "+1 555 555-5555", "extension": 5555}
    ]
}

Dengan menggunakan pendekatan ini, kami telah mendenormalisasi rekaman orang tersebut dengan menyematkan semua informasi yang terkait dengan orang ini, seperti detail dan alamat kontak mereka, ke dalam satu dokumen JSON . Selain itu, karena kami tidak terbatas pada skema tetap, kami memiliki fleksibilitas untuk melakukan hal-hal seperti memiliki detail kontak dengan berbagai bentuk sepenuhnya.

Mengambil rekaman orang lengkap dari database sekarang menjadi operasi baca tunggal terhadap satu kontainer untuk satu item. Memperbarui detail dan alamat kontak pada rekaman orang juga merupakan operasi tulis tunggal untuk satu item.

Mendenormalisasi data dapat mengurangi jumlah kueri dan memperbarui kebutuhan aplikasi Anda untuk menyelesaikan operasi umum.

Saat yang tepat untuk menyematkan

Secara umum, gunakan model data yang disematkan saat:

  • Ada hubungan yang terkandung antar entitas.
  • Ada hubungan satu-ke-beberapa antar entitas.
  • Data jarang berubah.
  • Data tidak tumbuh tanpa terikat.
  • Data sering dikueri bersama-sama.

Nota

Biasanya model data yang dinormalisasi memberikan performa baca yang lebih baik.

Saat yang tidak tepat untuk menyematkan

Meskipun aturan praktis di Azure Cosmos DB adalah untuk mendenormalisasi semuanya dan menyematkan semua data ke dalam satu item, pendekatan ini dapat menyebabkan situasi untuk dihindari.

Perhatikan cuplikan JSON ini.

{
    "id": "1",
    "name": "What's new in the coolest Cloud",
    "summary": "A blog post by someone real famous",
    "comments": [
        {"id": 1, "author": "anon", "comment": "something useful, I'm sure"},
        {"id": 2, "author": "bob", "comment": "wisdom from the interwebs"},
        …
        {"id": 100001, "author": "jane", "comment": "and on we go ..."},
        …
        {"id": 1000000001, "author": "angry", "comment": "blah angry blah angry"},
        …
        {"id": ∞ + 1, "author": "bored", "comment": "oh man, will this ever end?"},
    ]
}

Contoh ini mungkin seperti apa entitas postingan dengan komentar yang disematkan jika kami memodelkan blog biasa, atau sistem manajemen konten (CMS). Masalah dengan contoh ini adalah bahwa array komentar tidak terbatas, yang berarti tidak ada batas (praktis) untuk jumlah komentar yang dapat dimiliki oleh satu postingan. Desain ini dapat menyebabkan masalah karena ukuran item dapat tumbuh sangat besar, jadi hindari.

Ketika ukuran item meningkat, mengirimkan, membaca, dan memperbarui data dalam skala besar menjadi lebih menantang.

Dalam hal ini, akan lebih baik untuk mempertimbangkan model data berikut.

Post item:
{
    "id": "1",
    "name": "What's new in the coolest Cloud",
    "summary": "A blog post by someone real famous",
    "recentComments": [
        {"id": 1, "author": "anon", "comment": "something useful, I'm sure"},
        {"id": 2, "author": "bob", "comment": "wisdom from the interwebs"},
        {"id": 3, "author": "jane", "comment": "....."}
    ]
}

Comment items:
[
    {"id": 4, "postId": "1", "author": "anon", "comment": "more goodness"},
    {"id": 5, "postId": "1", "author": "bob", "comment": "tails from the field"},
    ...
    {"id": 99, "postId": "1", "author": "angry", "comment": "blah angry blah angry"},
    {"id": 100, "postId": "2", "author": "anon", "comment": "yet more"},
    ...
    {"id": 199, "postId": "2", "author": "bored", "comment": "will this ever end?"}   
]

Model ini memiliki item untuk setiap komentar dengan properti yang berisi pengidentifikasi postingan. Model ini memungkinkan posting berisi sejumlah komentar dan tumbuh secara efisien. Pengguna yang ingin melihat lebih banyak daripada komentar terbaru akan melakukan query pada kontainer ini dengan menggunakan postId, yang seharusnya menjadi kunci partisi untuk kontainer komentar.

Kasus lain di mana menyematkan data bukan ide yang baik adalah ketika data yang disematkan sering digunakan di seluruh item dan sering berubah.

Perhatikan cuplikan JSON ini.

{
    "id": "1",
    "firstName": "Thomas",
    "lastName": "Andersen",
    "holdings": [
        {
            "numberHeld": 100,
            "stock": { "symbol": "zbzb", "open": 1, "high": 2, "low": 0.5 }
        },
        {
            "numberHeld": 50,
            "stock": { "symbol": "xcxc", "open": 89, "high": 93.24, "low": 88.87 }
        }
    ]
}

Contoh ini dapat mewakili portofolio saham seseorang. Kami memilih untuk menyematkan informasi saham ke dalam setiap dokumen portofolio. Di lingkungan di mana data terkait sering berubah menyematkan data yang sering berubah berarti Anda terus memperbarui setiap portofolio. Dengan menggunakan contoh aplikasi perdagangan saham, Anda memperbarui setiap item portofolio setiap kali saham diperdagangkan.

Saham zbzb dapat diperdagangkan ratusan kali dalam satu hari, dan ribuan pengguna dapat memiliki zbzb dalam portofolio mereka. Dengan model data seperti contoh, sistem harus memperbarui ribuan dokumen portofolio berkali-kali setiap hari, yang tidak diskalakan dengan baik.

Data referensi

Menyematkan data berfungsi dengan baik dalam banyak kasus, tetapi ada skenario di mana denormalisasi data Anda menyebabkan lebih banyak masalah daripada nilainya. Jadi, apa yang bisa kau lakukan?

Anda dapat membuat hubungan antar entitas dalam database dokumen, bukan hanya dalam database relasional. Dalam database dokumen, satu item bisa menyertakan informasi yang tersambung ke data di dokumen lain. Azure Cosmos DB tidak dirancang untuk hubungan kompleks seperti yang ada dalam database relasional, tetapi tautan sederhana antara item dimungkinkan dan dapat membantu.

Di JSON, kami menggunakan contoh portofolio saham dari sebelumnya, tetapi kali ini kami merujuk ke item saham dalam portofolio alih-alih menyematkannya. Dengan cara ini, ketika item stok sering berubah sepanjang hari satu-satunya item yang perlu diperbarui adalah dokumen stok tunggal.

Person document:
{
    "id": "1",
    "firstName": "Thomas",
    "lastName": "Andersen",
    "holdings": [
        { "numberHeld":  100, "stockId": 1},
        { "numberHeld":  50, "stockId": 2}
    ]
}

Stock documents:
{
    "id": "1",
    "symbol": "zbzb",
    "open": 1,
    "high": 2,
    "low": 0.5,
    "vol": 11970000,
    "mkt-cap": 42000000,
    "pe": 5.89
},
{
    "id": "2",
    "symbol": "xcxc",
    "open": 89,
    "high": 93.24,
    "low": 88.87,
    "vol": 2970200,
    "mkt-cap": 1005000,
    "pe": 75.82
}

Salah satu kelemahan dari pendekatan ini adalah aplikasi Anda harus membuat beberapa permintaan database untuk mendapatkan informasi tentang setiap saham dalam portofolio seseorang. Desain ini membuat penulisan data lebih cepat, karena pembaruan sering terjadi. Namun, itu membuat membaca atau mengkueri data lebih lambat, yang kurang penting untuk sistem ini.

Nota

Model data yang dinormalisasi dapat memerlukan lebih banyak putaran ke server.

Bagaimana dengan kunci asing?

Karena tidak ada konsep batasan, seperti kunci asing, database tidak memverifikasi hubungan antardokumentasi dalam dokumen; tautan ini secara efektif "lemah." Jika Anda ingin memastikan bahwa data yang dimaksud item benar-benar ada, maka Anda perlu melakukan langkah ini di aplikasi Anda, atau dengan menggunakan pemicu sisi server atau prosedur tersimpan di Azure Cosmos DB.

Saat yang tepat untuk mereferensikan

Secara umum, gunakan model data yang dinormalkan saat:

  • Mewakili hubungan satu-ke-banyak.
  • Mewakili hubungan banyak-ke-banyak.
  • Data terkait sering berubah.
  • Data yang direferensikan dapat berupa tidak terikat.

Nota

Biasanya normalisasi memberikan performa tulis yang lebih baik.

Di mana saya meletakkan hubungan?

Pertumbuhan hubungan membantu menentukan item mana untuk menyimpan referensi.

Jika kita mengamati JSON yang memodelkan penerbit dan buku.

Publisher document:
{
    "id": "mspress",
    "name": "Microsoft Press",
    "books": [ 1, 2, 3, ..., 100, ..., 1000]
}

Book documents:
{"id": "1", "name": "Azure Cosmos DB 101" }
{"id": "2", "name": "Azure Cosmos DB for RDBMS Users" }
{"id": "3", "name": "Taking over the world one JSON doc at a time" }
...
{"id": "100", "name": "Learn about Azure Cosmos DB" }
...
{"id": "1000", "name": "Deep Dive into Azure Cosmos DB" }

Jika jumlah buku per penerbit kecil dan pertumbuhannya terbatas, menyimpan referensi buku di dalam item penerbit mungkin berguna. Namun, jika jumlah buku per penerbit tidak terbatas, model data ini akan menyebabkan array yang dapat diubah dan bertambah, seperti dalam contoh dokumen penerbit.

Mengalihkan struktur menghasilkan model yang mewakili data yang sama tetapi menghindari koleksi yang dapat diubah besar.

Publisher document:
{
    "id": "mspress",
    "name": "Microsoft Press"
}

Book documents:
{"id": "1","name": "Azure Cosmos DB 101", "pub-id": "mspress"}
{"id": "2","name": "Azure Cosmos DB for RDBMS Users", "pub-id": "mspress"}
{"id": "3","name": "Taking over the world one JSON doc at a time", "pub-id": "mspress"}
...
{"id": "100","name": "Learn about Azure Cosmos DB", "pub-id": "mspress"}
...
{"id": "1000","name": "Deep Dive into Azure Cosmos DB", "pub-id": "mspress"}

Dalam contoh ini, dokumen penerbit tidak lagi berisi koleksi yang tidak terbatas. Sebagai gantinya, setiap dokumen buku menyertakan referensi ke penerbitnya.

Bagaimana cara memodelkan relasi banyak ke banyak?

Dalam database relasional, hubungan banyak ke banyak sering dimodelkan dengan tabel gabungan. Hubungan ini hanya menggabungkan rekaman dari tabel lain bersama-sama.

Cuplikan layar memperlihatkan cara menggabungkan tabel.

Anda mungkin tergoda untuk mereplikasi hal yang sama menggunakan dokumen dan menghasilkan model data yang terlihat mirip dengan yang berikut ini.

Author documents:
{"id": "a1", "name": "Thomas Andersen" }
{"id": "a2", "name": "William Wakefield" }

Book documents:
{"id": "b1", "name": "Azure Cosmos DB 101" }
{"id": "b2", "name": "Azure Cosmos DB for RDBMS Users" }
{"id": "b3", "name": "Taking over the world one JSON doc at a time" }
{"id": "b4", "name": "Learn about Azure Cosmos DB" }
{"id": "b5", "name": "Deep Dive into Azure Cosmos DB" }

Joining documents:
{"authorId": "a1", "bookId": "b1" }
{"authorId": "a2", "bookId": "b1" }
{"authorId": "a1", "bookId": "b2" }
{"authorId": "a1", "bookId": "b3" }

Pendekatan ini berfungsi, tetapi memuat penulis dengan buku atau buku mereka dengan penulisnya selalu memerlukan setidaknya dua kueri database tambahan. Satu kueri ke item gabungan lalu kueri lain untuk mengambil item aktual yang sedang digabungkan.

Jika gabungan ini hanya menggabungkan dua bagian dari data, lalu mengapa tidak menghilangkan seluruhnya? Pertimbangkan contoh berikut.

Author documents:
{"id": "a1", "name": "Thomas Andersen", "books": ["b1", "b2", "b3"]}
{"id": "a2", "name": "William Wakefield", "books": ["b1", "b4"]}

Book documents:
{"id": "b1", "name": "Azure Cosmos DB 101", "authors": ["a1", "a2"]}
{"id": "b2", "name": "Azure Cosmos DB for RDBMS Users", "authors": ["a1"]}
{"id": "b3", "name": "Learn about Azure Cosmos DB", "authors": ["a1"]}
{"id": "b4", "name": "Deep Dive into Azure Cosmos DB", "authors": ["a2"]}

Dengan model ini, Anda dapat dengan mudah melihat buku mana yang ditulis penulis dengan melihat dokumen mereka. Anda juga dapat melihat penulis mana yang menulis buku dengan memeriksa dokumen buku. Anda tidak perlu menggunakan tabel gabungan terpisah atau membuat kueri tambahan. Model ini membuatnya lebih cepat dan lebih sederhana bagi aplikasi Anda untuk mendapatkan data yang dibutuhkan.

Model data hibrid

Kami menjelajahi penyematan (atau denormalisasi) dan mereferensikan (atau menormalkan) data. Setiap pendekatan menawarkan manfaat dan melibatkan trade-off.

Itu tidak selalu harus baik-atau. Jangan ragu untuk mencampur sedikit hal.

Berdasarkan pola penggunaan dan beban kerja khusus aplikasi Anda, mencampur data yang disematkan dan direferensikan mungkin masuk akal. Pendekatan ini dapat menyederhanakan logika aplikasi, mengurangi perjalanan pulang pergi server, dan mempertahankan performa yang baik.

Pertimbangkan JSON berikut.

Author documents:
{
    "id": "a1",
    "firstName": "Thomas",
    "lastName": "Andersen",
    "countOfBooks": 3,
    "books": ["b1", "b2", "b3"],
    "images": [
        {"thumbnail": "https://....png"}
        {"profile": "https://....png"}
        {"large": "https://....png"}
    ]
},
{
    "id": "a2",
    "firstName": "William",
    "lastName": "Wakefield",
    "countOfBooks": 1,
    "books": ["b1"],
    "images": [
        {"thumbnail": "https://....png"}
    ]
}

Book documents:
{
    "id": "b1",
    "name": "Azure Cosmos DB 101",
    "authors": [
        {"id": "a1", "name": "Thomas Andersen", "thumbnailUrl": "https://....png"},
        {"id": "a2", "name": "William Wakefield", "thumbnailUrl": "https://....png"}
    ]
},
{
    "id": "b2",
    "name": "Azure Cosmos DB for RDBMS Users",
    "authors": [
        {"id": "a1", "name": "Thomas Andersen", "thumbnailUrl": "https://....png"},
    ]
}

Di sini kita telah (sebagian besar) mengikuti model yang disematkan, di mana data dari entitas lain disematkan dalam dokumen tingkat atas, tetapi data lain direferensikan.

Jika Anda melihat dokumen buku, kita dapat menemukan beberapa hal menarik pada kumpulan penulis. Ada bidang id yang merupakan bidang yang kita gunakan untuk merujuk kembali ke dokumen penulis, praktik standar dalam model yang dinormalisasi, tetapi kemudian kita juga memiliki name dan thumbnailUrl. Kita hanya id dapat menggunakan dan membiarkan aplikasi mengambil informasi tambahan yang dibutuhkan dari item penulis yang sesuai menggunakan "tautan." Namun, karena aplikasi menampilkan nama penulis dan gambar mini dengan setiap buku, mendenormalisasi beberapa data dari penulis mengurangi jumlah perjalanan pulang pergi server per buku dalam daftar.

Jika nama penulis berubah atau mereka memperbarui foto mereka, Anda harus memperbarui setiap buku yang mereka terbitkan. Namun, untuk aplikasi ini, dengan asumsi penulis jarang mengubah namanya, kompromi ini adalah keputusan desain yang dapat diterima.

Dalam contoh, ada nilai agregat yang telah dihitung sebelumnya untuk menghemat pemrosesan mahal selama operasi baca. Dalam contoh, beberapa data yang disematkan dalam item penulis adalah data yang dihitung pada run-time. Setiap kali buku baru diterbitkan, item buku dibuat dan bidang countOfBooks diatur ke nilai terhitung berdasarkan jumlah dokumen buku yang ada untuk penulis tertentu. Optimalisasi ini akan baik dalam sistem yang intensif membaca di mana kita mampu melakukan komputasi pada penulisan untuk mengoptimalkan pembacaan.

Kemampuan untuk memiliki model dengan bidang yang telah dihitung sebelumnya dimungkinkan karena Azure Cosmos DB mendukung transaksi multi-dokumen. Banyak toko NoSQL tidak dapat melakukan transaksi di seluruh dokumen dan oleh karena itu menganjurkan keputusan desain seperti "selalu sematkan semuanya" karena keterbatasan ini. Dengan Azure Cosmos DB, Anda dapat menggunakan pemicu server atau prosedur tersimpan yang menyisipkan buku dan memperbarui penulis, semuanya dalam satu transaksi ACID. Sekarang Anda tidak perlu menyematkan semuanya ke dalam satu item hanya untuk memastikan bahwa data Anda tetap konsisten.

Membedakan antara jenis item yang berbeda

Dalam beberapa skenario, Anda mungkin ingin mencampur jenis item yang berbeda dalam koleksi yang sama; pilihan desain ini biasanya terjadi ketika Anda ingin beberapa dokumen terkait untuk duduk di partisi yang sama. Misalnya, Anda dapat menempatkan buku dan ulasan buku dalam koleksi yang sama dan mempartisinya dengan bookId. Dalam situasi seperti itu, Anda biasanya ingin menambahkan bidang ke dokumen Anda yang mengidentifikasi jenisnya untuk membedakannya.

Book documents:
{
    "id": "b1",
    "name": "Azure Cosmos DB 101",
    "bookId": "b1",
    "type": "book"
}

Review documents:
{
    "id": "r1",
    "content": "This book is awesome",
    "bookId": "b1",
    "type": "review"
}
{
    "id": "r2",
    "content": "Best book ever!",
    "bookId": "b1",
    "type": "review"
}

Pemodelan data untuk Mirroring Microsoft Fabric dan Azure Cosmos DB

Azure Cosmos DB Mirroring adalah kemampuan pemrosesan transaksional dan analitik hibrid asli cloud (HTAP) yang memungkinkan Anda menjalankan analitik mendekati real-time melalui data operasional di Azure Cosmos DB. Fabric Mirroring menciptakan integrasi yang mulus antara Azure Cosmos DB dan OneLake di Microsoft Fabric.

Integrasi ini memungkinkan Anda menjalankan kueri yang cepat dan terjangkau pada sekumpulan data yang besar. Anda tidak perlu menyalin data atau khawatir tentang memengaruhi beban kerja transaksi anda. Saat Anda mengaktifkan Mirroring untuk kontainer, setiap perubahan yang Anda buat pada data Anda akan segera disalin ke OneLake. Anda tidak perlu menyiapkan umpan perubahan atau menjalankan pekerjaan ekstrak, transformasi, dan pemuatan (ETL). Sistem membuat kedua penyimpanan tetap sinkron untuk Anda.

Dengan Azure Cosmos DB Mirroring, Anda sekarang dapat langsung terhubung ke kontainer Azure Cosmos DB dari Microsoft Fabric dan mengakses data Anda tanpa biaya Unit Permintaan (unit permintaan) menggunakan kueri T-SQL melalui titik akhir SQL ke data Anda atau Spark langsung dari OneLake.

Inferensi skema otomatis

Penyimpanan transaksional Azure Cosmos DB adalah data semi-terstruktur berorientasi baris, sedangkan OneLake di Microsoft Fabric menggunakan format kolom dan terstruktur. Konversi ini secara otomatis dibuat untuk pelanggan. Terdapat batasan dalam proses konversi: jumlah maksimum tingkat berlapis, jumlah maksimum properti, jenis data yang tidak didukung, dan lainnya.

Nota

Dalam konteks penyimpanan analitik, kami menganggap struktur berikut sebagai properti:

  • JSON "elemen" atau "pasangan nilai string dipisahkan oleh :"
  • Objek JSON, dibatasi oleh { dan }
  • Array JSON, dibatasi oleh [ dan ]

Anda dapat meminimalkan efek konversi inferensi skema, dan memaksimalkan kemampuan analitik Anda, dengan menggunakan teknik berikut.

Normalisasi

Normalisasi menjadi kurang relevan karena Microsoft Fabric memungkinkan Anda menggabungkan kontainer menggunakan T-SQL atau Spark SQL. Keuntungan normalisasi yang diharapkan adalah:

  • Jejak data yang lebih kecil.
  • Transaksi lebih kecil.
  • Lebih sedikit properti per dokumen.
  • Struktur data dengan tingkat berlapis lebih sedikit.

Memiliki lebih sedikit properti dan lebih sedikit tingkat dalam data Anda membuat kueri analitis lebih cepat. Ini juga membantu memastikan bahwa semua bagian data Anda disertakan dalam OneLake. Ada batasan jumlah tingkat dan properti yang diwakili dalam OneLake.

Faktor penting lainnya untuk normalisasi adalah OneLake mendukung tataan hasil hingga 1.000 kolom, dan mengekspos kolom berlapis juga diperhitungkan dalam batas tersebut. Dengan kata lain, titik akhir SQL di Fabric memiliki batas 1.000 properti.

Namun, apa yang harus dilakukan karena denormalisasi adalah teknik pemodelan data yang penting untuk Azure Cosmos DB? Jawabannya adalah Anda harus menemukan keseimbangan yang tepat untuk beban kerja transaksional dan analitis Anda.

Kunci Partisi

Kunci partisi Azure Cosmos DB (PK) tidak digunakan di Microsoft Fabric. Karena isolasi ini, Anda dapat memilih PK untuk data transaksional Anda dengan fokus pada penyerapan data dan pembacaan titik, sementara kueri lintas partisi dapat dilakukan Microsoft Fabric. Mari kita lihat contohnya:

Dalam skenario IoT global hipotetis, device id berfungsi sebagai kunci partisi yang baik karena semua perangkat menghasilkan volume data yang sama, yang mencegah masalah partisi panas. Tetapi jika Anda ingin menganalisis data lebih dari satu perangkat, seperti "semua data dari kemarin" atau "total per kota", Anda mungkin memiliki masalah karena kueri tersebut adalah kueri lintas partisi. Kueri tersebut dapat merusak performa transaksional Anda karena menggunakan sebagian throughput dalam unit permintaan untuk dijalankan. Tetapi dengan Microsoft Fabric, Anda dapat menjalankan kueri analitik ini tanpa biaya unit permintaan. Format delta di OneLake dioptimalkan untuk kueri analitis.

Jenis data dan nama properti

Artikel aturan inferensi skema otomatis mencantumkan jenis data yang didukung. Meskipun runtime Microsoft Fabric mungkin memproses jenis data yang didukung secara berbeda, jenis data yang tidak didukung memblokir representasi di penyimpanan analitis. Salah satu contohnya adalah: Saat menggunakan string DateTime yang mengikuti standar ISO 8601 UTC, kumpulan Spark di Microsoft Fabric mewakili kolom ini karena string dan SQL tanpa server mewakili kolom ini sebagai varchar(8000).

Penghalusan data

Setiap properti di tingkat atas data Azure Cosmos DB Anda menjadi kolom di penyimpanan analitik. Properti di dalam objek atau array berlapis disimpan sebagai JSON di OneLake. Struktur berlapis menuntut pemrosesan tambahan dari runtime Spark atau SQL untuk meratakan data. Ini dapat menambahkan biaya komputasi dan latensi saat berhadapan dengan data dalam jumlah yang sangat besar. Jika mudah untuk melakukannya, gunakan model datar untuk data Anda. Paling tidak, hindari bersarangnya data yang berlebihan dalam model data Anda.

Item hanya memiliki dua kolom di OneLake, id dan contactDetails. Semua data lainnya, email, dan phone, memerlukan pemrosesan tambahan melalui fungsi SQL atau Spark untuk dibaca.

{
    "id": "1",
    "contactDetails": [
        {"email": "thomas@andersen.com"},
        {"phone": "+1 555 555-5555"}
    ]
}

Proses meratakan menghilangkan kebutuhan ini. Di bawah ini, id, email, dan phone semuanya dapat diakses secara langsung sebagai kolom tanpa pemrosesan tambahan

{
    "id": "1",
    "email": "thomas@andersen.com",
    "phone": "+1 555 555-5555"
}

Pelapisan data

Microsoft Fabric memungkinkan Anda mengurangi biaya dari perspektif berikut:

  • Lebih sedikit kueri yang berjalan di database transaksional.
  • PK yang dioptimalkan untuk penyerapan data dan pembacaan titik, mengurangi ruang data, skenario partisi panas, dan pemisahan partisi.
  • Tidak ada pekerjaan ETL yang berjalan di lingkungan Anda, yang berarti Anda tidak perlu mengalokasikan unit permintaan untuk mereka.

Redundansi terkontrol

Teknik ini adalah alternatif yang bagus untuk situasi ketika model data sudah ada dan tidak dapat diubah. Atau jika data Anda terlalu kompleks dengan terlalu banyak tingkat berlapis atau terlalu banyak properti. Jika skenario ini adalah kasus Anda, Anda dapat menggunakan Umpan Perubahan Azure Cosmos DB untuk mereplikasi data Anda ke kontainer lain, menerapkan transformasi yang diperlukan, lalu mengonfigurasi Mirroring untuk kontainer tersebut ke Microsoft Fabric untuk analitik. Mari kita lihat contohnya:

Scenario

Kontainer CustomersOrdersAndItems digunakan untuk menyimpan pesanan on-line termasuk detail pelanggan dan item: alamat penagihan, alamat pengiriman, metode pengiriman, status pengiriman, harga item, dll. Hanya 1.000 properti pertama yang diwakili dan informasi utama tidak disertakan, membuat analitik dalam Fabric tidak mungkin. Kontainer memiliki petabyte data sehingga tidak dimungkinkan untuk mengubah aplikasi dan merombak data.

Aspek lain dari masalah ini adalah volume data yang besar. Miliaran baris terus digunakan oleh Departemen Analitik, yang mencegahnya untuk menggunakan tttl untuk penghapusan data lama. Mempertahankan seluruh riwayat data dalam database transaksi karena kebutuhan analitik memaksa mereka untuk selalu meningkatkan RU/dtk, yang berdampak pada peningkatan biaya. Beban kerja transaksional dan analitis bersaing untuk sumber daya yang sama secara bersamaan.

Apa yang bisa Anda lakukan?

Solusi dengan Pengubahan Umpan

  • Solusinya adalah menggunakan Umpan Perubahan untuk mengisi tiga kontainer baru: Customers, , Ordersdan Items. Dengan Umpan Perubahan, Anda dapat menormalkan dan meratakan data dan menghapus informasi yang tidak perlu dari model data.
  • Kontainer CustomersOrdersAndItems sekarang memiliki time-to-live (TTL) yang diatur untuk menyimpan data selama enam bulan saja, yang memungkinkan pengurangan penggunaan unit permintaan lain, karena ada minimal satu unit permintaan per GB di Azure Cosmos DB. Lebih sedikit data, maka lebih sedikit unit permintaan.

Takeaways

Pengalihan terbesar dari artikel ini adalah bahwa pemodelan data dalam skenario bebas skema sama pentingnya dengan sebelumnya.

Sama seperti tidak adanya cara tunggal untuk mewakili sepotong data di layar, tidak ada pula cara tunggal untuk memodelkan data Anda. Anda perlu memahami aplikasi Anda dan bagaimana aplikasi menghasilkan, mengonsumsi, dan memproses data. Dengan menerapkan pedoman yang disajikan di sini, Anda dapat membuat model yang memenuhi kebutuhan langsung aplikasi Anda. Saat aplikasi Anda berubah, gunakan fleksibilitas database bebas skema untuk beradaptasi dan mengembangkan model data Anda dengan mudah.