{"id":35954,"date":"2025-12-06T03:31:17","date_gmt":"2025-12-06T00:31:17","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/"},"modified":"2025-12-06T03:31:17","modified_gmt":"2025-12-06T00:31:17","slug":"amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/","title":{"rendered":"Amazon DynamoDB ile Veri Modellemenin G\u00fcc\u00fc Nereden Geliyor?"},"content":{"rendered":"<article>\nAmazon DynamoDB ile \u0130leri D\u00fczey Veri Modelleme Teknikleri<\/p>\n<p>Modern bulut uygulamalar\u0131n\u0131n vazge\u00e7ilmez bir bile\u015feni olan veritabanlar\u0131, s\u00fcrekli artan veri hacmi ve kullan\u0131c\u0131 talepleri kar\u015f\u0131s\u0131nda geleneksel yakla\u015f\u0131mlarla yetersiz kalabilmektedir. Bu noktada, y\u00fcksek performansl\u0131 ve \u00f6l\u00e7eklenebilir \u00e7\u00f6z\u00fcmlere duyulan ihtiya\u00e7, sunucusuz ve NoSQL veritabanlar\u0131n\u0131 \u00f6n plana \u00e7\u0131karmaktad\u0131r. Amazon DynamoDB, bu ihtiya\u00e7lar\u0131 kar\u015f\u0131lamak \u00fczere tasarlanm\u0131\u015f, tam y\u00f6netilen, anahtar-de\u011fer ve belge veritaban\u0131 hizmeti olarak \u00f6ne \u00e7\u0131kar. Ancak, DynamoDB&#8217;nin ger\u00e7ek g\u00fcc\u00fcn\u00fc ortaya \u00e7\u0131karmak, sadece temel kullan\u0131mla s\u0131n\u0131rl\u0131 kalmay\u0131p, ileri d\u00fczey veri modelleme tekniklerini anlamaktan ve uygulamaktan ge\u00e7er. Bu makale, AWS re:Invent 2025&#8217;teki DAT414 oturumunun ruhunu yans\u0131tarak, DynamoDB ile veri modellemenin derinliklerine inecek, tek tablo tasar\u0131m\u0131ndan karma\u015f\u0131k eri\u015fim desenlerine kadar \u00e7e\u015fitli stratejileri ger\u00e7ek d\u00fcnya senaryolar\u0131yla a\u00e7\u0131klayacakt\u0131r.<\/p>\n<p>G\u00fcn\u00fcm\u00fcz\u00fcn h\u0131zla de\u011fi\u015fen dijital d\u00fcnyas\u0131nda, uygulamalar\u0131n s\u00fcrekli olarak daha fazla veri i\u015flemesi, daha d\u00fc\u015f\u00fck gecikme s\u00fcresiyle yan\u0131t vermesi ve trilyonlarca iste\u011fi sorunsuz bir \u015fekilde kar\u015f\u0131lamas\u0131 beklenmektedir. Geleneksel ili\u015fkisel veritabanlar\u0131, belirli bir \u00f6l\u00e7e\u011fe kadar bu beklentileri kar\u015f\u0131layabilse de, genellikle y\u00fcksek trafikli, d\u00fc\u015f\u00fck gecikmeli ve y\u00fcksek \u00f6l\u00e7eklenebilirlik gerektiren i\u015f y\u00fckleri i\u00e7in darbo\u011faz olu\u015fturma potansiyeli ta\u015f\u0131r. \u0130\u015fte tam da bu noktada, Amazon DynamoDB gibi NoSQL veritabanlar\u0131 sahneye \u00e7\u0131karak, bu zorluklara modern bir \u00e7\u00f6z\u00fcm sunar. Tamamen y\u00f6netilen yap\u0131s\u0131 sayesinde altyap\u0131 y\u00f6netimi y\u00fck\u00fcn\u00fc ortadan kald\u0131r\u0131r ve geli\u015ftiricilerin sadece uygulamalar\u0131na odaklanmas\u0131n\u0131 sa\u011flar. Ancak, DynamoDB&#8217;nin sundu\u011fu bu m\u00fcthi\u015f potansiyelin tamam\u0131n\u0131 kullanabilmek i\u00e7in, onu sadece bir veri depolama alan\u0131 olarak g\u00f6rmek yeterli de\u011fildir; veri eri\u015fim desenlerinizi (access patterns) temel alan ileri d\u00fczey bir modelleme yakla\u015f\u0131m\u0131 benimsemek kritik \u00f6neme sahiptir.<\/p>\n<p>Peki, DynamoDB&#8217;nin performans\u0131 ve \u00f6l\u00e7eklenebilirli\u011fi nereden geliyor ve biz bunu veri modellemeyle nas\u0131l daha da peki\u015ftirebiliriz? Cevap, onun da\u011f\u0131t\u0131k mimarisinde, anahtar-de\u011fer yap\u0131s\u0131nda ve verilerinizi fiziksel olarak nas\u0131l organize etti\u011finde sakl\u0131. DynamoDB, verilerinizi partition&#8217;lara (b\u00f6l\u00fcmlere) ay\u0131rarak, her bir b\u00f6l\u00fcm\u00fc ayr\u0131 sunucularda saklar. Bu sayede, gelen iste\u011fi do\u011fru b\u00f6l\u00fcme y\u00f6nlendirerek paralel i\u015fleme ve inan\u0131lmaz h\u0131zlar elde eder. Ancak bu da\u011f\u0131t\u0131m, do\u011fru Partition Key (B\u00f6l\u00fcm Anahtar\u0131) se\u00e7imiyle ba\u015flar. Yanl\u0131\u015f bir anahtar se\u00e7imi, t\u00fcm veriyi tek bir b\u00f6l\u00fcme y\u0131\u011farak &#8220;hot partition&#8221; ad\u0131 verilen darbo\u011fazlara yol a\u00e7abilir. Bu da performans\u0131 d\u00fc\u015f\u00fcr\u00fcr, maliyetleri art\u0131r\u0131r ve \u00f6l\u00e7eklenebilirlik vaadini bo\u015fa \u00e7\u0131kar\u0131r. Bu nedenle, DynamoDB&#8217;de veri modelleme, uygulaman\u0131z\u0131n veriye nas\u0131l eri\u015fece\u011fini \u00f6nceden dikkatlice planlamak anlam\u0131na gelir. Bu planlama, ili\u015fkisel veritabanlar\u0131ndaki normalizasyon yakla\u015f\u0131mlar\u0131ndan temelde farkl\u0131d\u0131r. \u0130li\u015fkisel d\u00fcnyada verileri tekrar etmemek i\u00e7in normalizasyon yaparken, DynamoDB d\u00fcnyas\u0131nda performans i\u00e7in denormalizasyonu ve eri\u015fim desenlerine \u00f6zel tasar\u0131mlar\u0131 kucaklar\u0131z. Bu derinlemesine anlay\u0131\u015f ve do\u011fru uygulama, re:Invent 2025&#8217;teki DAT414 oturumunun da temel oda\u011f\u0131 olan ileri d\u00fczey DynamoDB veri modelleme tekniklerinin kap\u0131lar\u0131n\u0131 aralayacakt\u0131r.<\/p>\n<h2>Amazon DynamoDB&#8217;nin Temellerini Anlamak: Neden \u00d6nemli?<\/h2>\n<p>DynamoDB&#8217;nin ileri d\u00fczey modelleme tekniklerine ge\u00e7meden \u00f6nce, temel kavramlar\u0131n\u0131 sa\u011flam bir \u015fekilde anlamak hayati \u00f6neme sahiptir. Bir NoSQL veritaban\u0131 olarak DynamoDB, ili\u015fkisel veritabanlar\u0131n\u0131n aksine \u00f6nceden tan\u0131mlanm\u0131\u015f \u015femalara s\u0131k\u0131 s\u0131k\u0131ya ba\u011fl\u0131 kalmaz, bu da geli\u015ftiricilere esneklik sunar. Ancak bu esneklik, belirli tasar\u0131m k\u0131s\u0131tlamalar\u0131n\u0131 ve en iyi uygulamalar\u0131 g\u00f6z ard\u0131 etmeniz gerekti\u011fi anlam\u0131na gelmez; tam tersine, DynamoDB&#8217;nin benzersiz yap\u0131s\u0131ndan maksimum fayda sa\u011flamak i\u00e7in bu k\u0131s\u0131tlamalar\u0131 anlamak ve bunlara uygun modelleme yapmak gerekir. DynamoDB&#8217;nin kalbinde iki temel kavram yatar: Partition Key ve Sort Key.<\/p>\n<p><strong>Partition Key (B\u00f6l\u00fcm Anahtar\u0131):<\/strong> Bir DynamoDB tablosundaki her \u00f6\u011fe (item), bir Partition Key&#8217;e sahip olmak zorundad\u0131r. Bu anahtar, verilerin DynamoDB&#8217;nin depolama d\u00fc\u011f\u00fcmleri aras\u0131nda fiziksel olarak nas\u0131l da\u011f\u0131t\u0131laca\u011f\u0131n\u0131 belirler. \u0130yi se\u00e7ilmi\u015f bir Partition Key, verileri e\u015fit bir \u015fekilde da\u011f\u0131tarak performans darbo\u011fazlar\u0131n\u0131 \u00f6nler ve uygulaman\u0131z\u0131n \u00f6l\u00e7eklenmesini sa\u011flar. \u00d6rne\u011fin, bir <code>KullaniciID<\/code> Partition Key olarak se\u00e7ildi\u011finde, her bir kullan\u0131c\u0131n\u0131n verileri ayr\u0131 bir b\u00f6l\u00fcmde depolan\u0131r veya daha fazla veri i\u00e7in geni\u015fletilebilir. A\u015f\u0131r\u0131 derecede s\u0131k kullan\u0131lan bir Partition Key (d\u00fc\u015f\u00fck kardinaliteye sahip bir anahtar), t\u00fcm isteklerin tek bir b\u00f6l\u00fcme y\u00f6nelmesine neden olarak &#8220;hot partition&#8221; sorununa yol a\u00e7abilir.<\/p>\n<p><strong>Sort Key (S\u0131ralama Anahtar\u0131):<\/strong> \u0130ste\u011fe ba\u011fl\u0131 olan Sort Key, ayn\u0131 Partition Key&#8217;e sahip \u00f6\u011felerin belirli bir s\u0131rada saklanmas\u0131n\u0131 sa\u011flar. Bir Partition Key ile bir Sort Key kombinasyonu, tablodaki her \u00f6\u011feyi benzersiz bir \u015fekilde tan\u0131mlar. Bu ikiliye &#8220;Composite Primary Key&#8221; (Birle\u015fik Birincil Anahtar) denir. Sort Key, belirli bir Partition Key alt\u0131ndaki \u00f6\u011feleri sorgularken aral\u0131k sorgular\u0131 (range queries) yapman\u0131za olanak tan\u0131r. \u00d6rne\u011fin, bir <code>KullaniciID<\/code> ile <code>SiparisTarihi<\/code> Sort Key olarak belirlendi\u011finde, bir kullan\u0131c\u0131n\u0131n belirli bir tarih aral\u0131\u011f\u0131ndaki sipari\u015flerini kolayca sorgulayabilirsiniz. Bu \u00f6zellik, verileri hiyerar\u015fik veya zamansal olarak d\u00fczenlemek i\u00e7in inan\u0131lmaz derecede g\u00fc\u00e7l\u00fcd\u00fcr.<\/p>\n<p>Bu anahtar yap\u0131lar\u0131n\u0131n \u00f6tesinde, DynamoDB&#8217;nin esnek \u015femas\u0131, her \u00f6\u011fenin farkl\u0131 niteliklere (attributes) sahip olabilmesine izin verir. Ancak bu esneklik, karma\u015f\u0131k sorgular\u0131 do\u011frudan birincil anahtar \u00fczerinde yapamayaca\u011f\u0131n\u0131z anlam\u0131na gelir. \u0130\u015fte bu noktada <strong>Global Secondary Indexes (GSI)<\/strong> ve <strong>Local Secondary Indexes (LSI)<\/strong> devreye girer.<\/p>\n<p>*   <strong>Global Secondary Index (GSI):<\/strong> Veri modellemenin en g\u00fc\u00e7l\u00fc ara\u00e7lar\u0131ndan biridir. Ana tablonun birincil anahtar\u0131ndan farkl\u0131 bir Partition Key ve iste\u011fe ba\u011fl\u0131 bir Sort Key&#8217;e sahip bir ikincil dizindir. Bu, ana tabloya farkl\u0131 bir eri\u015fim deseniyle sorgu yapman\u0131za olanak tan\u0131r. \u00d6rne\u011fin, <code>KullaniciID<\/code> ve <code>SiparisTarihi<\/code> birincil anahtarken, sipari\u015fleri <code>SiparisDurumu<\/code> ve <code>SiparisTutari<\/code>&#8216;na g\u00f6re sorgulamak isterseniz bir GSI tan\u0131mlayabilirsiniz. GSI&#8217;lar, ana tablodan tamamen ba\u011f\u0131ms\u0131z bir okuma\/yazma kapasitesine sahip olabilir ve veriler \u00fczerinde farkl\u0131 g\u00f6r\u00fcn\u00fcmler sunar.<br \/>\n*   <strong>Local Secondary Index (LSI):<\/strong> Ana tablonun Partition Key&#8217;iyle ayn\u0131 Partition Key&#8217;e sahip olmal\u0131, ancak farkl\u0131 bir Sort Key&#8217;e sahip olmal\u0131d\u0131r. LSI&#8217;lar, ayn\u0131 Partition Key alt\u0131nda farkl\u0131 s\u0131ralama ve sorgulama se\u00e7enekleri sunar. Ana tablonun kapasitesini kullan\u0131r ve daha kat\u0131 limitlere sahiptir.<\/p>\n<p>DynamoDB&#8217;deki veri modelleme, uygulaman\u0131z\u0131n ihtiya\u00e7 duydu\u011fu t\u00fcm eri\u015fim desenlerini (\u00f6rne\u011fin, &#8220;belirli bir kullan\u0131c\u0131n\u0131n t\u00fcm sipari\u015flerini getir&#8221;, &#8220;son 24 saatteki t\u00fcm bekleyen sipari\u015fleri bul&#8221;, &#8220;belirli bir \u00fcr\u00fcn\u00fcn t\u00fcm incelemelerini listele&#8221;) g\u00f6z \u00f6n\u00fcnde bulundurarak ba\u015flar. \u0130li\u015fkisel veritabanlar\u0131nda &#8220;\u00f6nce \u015femay\u0131 tasarla, sonra sorgula&#8221; yakla\u015f\u0131m\u0131 varken, DynamoDB&#8217;de &#8220;\u00f6nce eri\u015fim desenlerini tan\u0131mla, sonra \u015femay\u0131 modelle&#8221; yakla\u015f\u0131m\u0131 benimsenir. Bu temel anlay\u0131\u015f, sonraki b\u00f6l\u00fcmlerde ele alaca\u011f\u0131m\u0131z ileri d\u00fczey tekniklerin temelini olu\u015fturur ve uygulaman\u0131z\u0131n hem performans hem de maliyet a\u00e7\u0131s\u0131ndan optimize edilmesini sa\u011flar.<\/p>\n<h2>\u0130leri D\u00fczey Veri Modelleme Teknikleri: Tek Tablo Yakla\u015f\u0131m\u0131 (Single-Table Design) Neden Daha \u0130yidir ve Nas\u0131l Uygulan\u0131r?<\/h2>\n<p>Amazon DynamoDB ile veri modellemede en g\u00fc\u00e7l\u00fc ve ayn\u0131 zamanda ba\u015flang\u0131\u00e7ta en kafa kar\u0131\u015ft\u0131r\u0131c\u0131 yakla\u015f\u0131mlardan biri, &#8220;tek tablo tasar\u0131m\u0131&#8221; veya &#8220;single-table design&#8221;d\u0131r. Geleneksel ili\u015fkisel veritabanlar\u0131 ge\u00e7mi\u015finden gelen geli\u015ftiriciler i\u00e7in, farkl\u0131 varl\u0131k t\u00fcrlerini (\u00f6rne\u011fin, kullan\u0131c\u0131lar, sipari\u015fler, \u00fcr\u00fcnler, incelemeler) ayr\u0131 tablolarda tutmak do\u011fal bir yakla\u015f\u0131md\u0131r. Ancak DynamoDB&#8217;nin do\u011fas\u0131 gere\u011fi, bir\u00e7ok durumda bu yakla\u015f\u0131m optimum de\u011fildir. Tek tablo tasar\u0131m\u0131, birden fazla varl\u0131k t\u00fcr\u00fcn\u00fc tek bir DynamoDB tablosunda depolayarak performans\u0131 art\u0131r\u0131r, maliyetleri d\u00fc\u015f\u00fcr\u00fcr ve operasyonel karma\u015f\u0131kl\u0131\u011f\u0131 azalt\u0131r.<\/p>\n<p><strong>Neden Tek Tablo Tasar\u0131m\u0131?<\/strong><\/p>\n<p>1.  <strong>Maliyet Optimizasyonu:<\/strong> DynamoDB&#8217;de her tablonun belirli bir operasyonel y\u00fck\u00fc vard\u0131r (\u00f6rne\u011fin, yedekleme, kurtarma, izleme). Tek bir tablo kullanmak, bu operasyonel y\u00fck\u00fc ve ili\u015fkili maliyetleri minimumda tutar. Ayr\u0131ca, her tablo i\u00e7in ayr\u0131 ayr\u0131 okuma\/yazma kapasitesi sa\u011flamak yerine, tek bir tabloya atanan kapasite t\u00fcm varl\u0131k t\u00fcrleri aras\u0131nda payla\u015ft\u0131r\u0131labilir, bu da genel kapasite kullan\u0131m\u0131n\u0131 optimize eder.<br \/>\n2.  <strong>Geli\u015fmi\u015f Performans:<\/strong> \u00d6zellikle ilgili verilerin s\u0131k s\u0131k birlikte eri\u015fildi\u011fi durumlarda, tek tablo tasar\u0131m\u0131 daha az a\u011f \u00e7a\u011fr\u0131s\u0131 (network round-trip) gerektirdi\u011finden performans\u0131 art\u0131r\u0131r. \u00d6rne\u011fin, bir kullan\u0131c\u0131n\u0131n profilini ve son be\u015f sipari\u015fini tek bir Partition Key sorgusuyla getirebilirsiniz. Bu, birden fazla ayr\u0131 tabloya yap\u0131lan ayr\u0131 sorgulardan \u00e7ok daha h\u0131zl\u0131d\u0131r.<br \/>\n3.  <strong>Atomik \u0130\u015flemler:<\/strong> DynamoDB, tek bir Partition Key alt\u0131ndaki \u00f6\u011feler \u00fczerinde atomik i\u015flemler (transactional writes\/updates) yap\u0131lmas\u0131na olanak tan\u0131r. Farkl\u0131 varl\u0131k t\u00fcrlerini ayn\u0131 Partition Key alt\u0131nda birle\u015ftirmek, karma\u015f\u0131k i\u015f mant\u0131klar\u0131n\u0131n atomik olarak i\u015flenmesini kolayla\u015ft\u0131r\u0131r.<br \/>\n4.  <strong>Basitle\u015ftirilmi\u015f Geli\u015ftirme:<\/strong> Daha az tablo, y\u00f6netim y\u00fck\u00fcn\u00fc azalt\u0131r. Uygulama kodunda daha az tablo ad\u0131, daha az kapasite y\u00f6netimi ve daha az g\u00fcvenlik politikas\u0131 anlam\u0131na gelir.<\/p>\n<p><strong>Tek Tablo Tasar\u0131m\u0131 Nas\u0131l Uygulan\u0131r?<\/strong><\/p>\n<p>Tek tablo tasar\u0131m\u0131n\u0131n temelinde, DynamoDB&#8217;nin g\u00fc\u00e7l\u00fc Partition Key ve Sort Key mekanizmas\u0131n\u0131, birden fazla varl\u0131k t\u00fcr\u00fcn\u00fc depolamak ve sorgulamak i\u00e7in &#8220;a\u015f\u0131r\u0131 y\u00fcklemek&#8221; (overloading) yatar. \u0130\u015fte temel ad\u0131mlar:<\/p>\n<p>1.  <strong>Jenerik Anahtar Adlar\u0131:<\/strong> <code>PK<\/code> (Partition Key) ve <code>SK<\/code> (Sort Key) gibi jenerik anahtar adlar\u0131 kullan\u0131n. Bu, farkl\u0131 varl\u0131k t\u00fcrlerinin bu anahtarlar\u0131 kendi \u00f6zel verileriyle doldurmas\u0131n\u0131 sa\u011flar.<br \/>\n2.  <strong>Varl\u0131k T\u00fcr\u00fc Belirleyiciler:<\/strong> Her \u00f6\u011fe i\u00e7in bir <code>EntityType<\/code> veya <code>Type<\/code> niteli\u011fi ekleyin. Bu, ayn\u0131 <code>PK<\/code>\/<code>SK<\/code> kombinasyonuna sahip olsa bile, hangi verinin hangi varl\u0131\u011fa ait oldu\u011funu anlaman\u0131za yard\u0131mc\u0131 olur.<br \/>\n3.  <strong>Karma\u015f\u0131k Sort Key&#8217;ler:<\/strong> Sort Key&#8217;i, farkl\u0131 varl\u0131k t\u00fcrleri i\u00e7in farkl\u0131 ama\u00e7larla kullan\u0131n. \u00d6rne\u011fin, bir <code>USER#<UserID><\/code> PK&#8217;si alt\u0131nda, <code>PROFILE#<UserID><\/code> SK&#8217;si kullan\u0131c\u0131 profili i\u00e7in, <code>ORDER#<OrderID><\/code> SK&#8217;si sipari\u015fler i\u00e7in, <code>REVIEW#<ReviewID><\/code> SK&#8217;si ise \u00fcr\u00fcn incelemeleri i\u00e7in kullan\u0131labilir. Bu, tek bir sorguyla ilgili t\u00fcm varl\u0131klar\u0131 \u00e7ekmenize olanak tan\u0131r.<br \/>\n4.  <strong>Global Secondary Index (GSI) Kullan\u0131m\u0131:<\/strong> Tek tablo tasar\u0131m\u0131, ana tablonun birincil eri\u015fim desenlerine odaklan\u0131rken, GSI&#8217;lar farkl\u0131 sorgulama ihtiya\u00e7lar\u0131 i\u00e7in esneklik sa\u011flar. \u00d6rne\u011fin, ana tabloda kullan\u0131c\u0131 ve sipari\u015f verilerini <code>USER#<UserID><\/code> PK alt\u0131nda tutarken, t\u00fcm sipari\u015fleri <code>ORDER_STATUS#<Status><\/code> PK ile sorgulamak i\u00e7in bir GSI tan\u0131mlayabilirsiniz.<\/p>\n<div class=\"tip-box\">\n  Uzman \u0130pucu: Tek tablo tasar\u0131m\u0131nda en b\u00fcy\u00fck zorluk, t\u00fcm eri\u015fim desenlerinizi \u00f6nceden detayl\u0131ca planlamakt\u0131r. Bu, gelecekteki de\u011fi\u015fiklikleri minimize eder ve esneklik sa\u011flar. Aksi takdirde, tablo yeniden yap\u0131land\u0131rma maliyetli olabilir.\n<\/div>\n<p><strong>Vaka Analizi: E-ticaret Platformu Veri Modeli<\/strong><\/p>\n<p>Bir e-ticaret platformunda kullan\u0131c\u0131lar, sipari\u015fler, \u00fcr\u00fcnler ve incelemeler gibi farkl\u0131 varl\u0131klar bulunur. Geleneksel yakla\u015f\u0131mda her biri ayr\u0131 bir tablo olurdu. Tek tablo tasar\u0131m\u0131 ile nas\u0131l modelleyebiliriz?<\/p>\n<p>| Anahtar | A\u00e7\u0131klama |<br \/>\n| :&#8212;&#8212;- | :&#8212;&#8212;&#8211; |<br \/>\n| <code>PK<\/code> | Partition Key &#8211; Varl\u0131k t\u00fcr\u00fcne g\u00f6re de\u011fi\u015fir |<br \/>\n| <code>SK<\/code> | Sort Key &#8211; Varl\u0131k t\u00fcr\u00fcne g\u00f6re de\u011fi\u015fir |<br \/>\n| <code>Type<\/code> | Varl\u0131k tipini (USER, ORDER, PRODUCT, REVIEW) belirtir |<br \/>\n| <code>Data<\/code> | JSON veya di\u011fer ek veriler |<br \/>\n| <code>GSI1PK<\/code> | Global Secondary Index 1 Partition Key |<br \/>\n| <code>GSI1SK<\/code> | Global Secondary Index 1 Sort Key |<\/p>\n<p><strong>\u00d6rnek Veri Yap\u0131s\u0131:<\/strong><\/p>\n<p>*   <strong>Kullan\u0131c\u0131 (USER) Profili:<\/strong><br \/>\n    *   <code>PK<\/code>: <code>USER#<UserID><\/code><br \/>\n    *   <code>SK<\/code>: <code>PROFILE#<UserID><\/code><br \/>\n    *   <code>Type<\/code>: <code>USER<\/code><br \/>\n    *   <code>Ad<\/code>: &#8220;Ay\u015fe Y\u0131lmaz&#8221;, <code>Email<\/code>: &#8220;ayse@example.com&#8221;<br \/>\n*   <strong>Sipari\u015f (ORDER):<\/strong><br \/>\n    *   <code>PK<\/code>: <code>USER#<UserID><\/code><br \/>\n    *   <code>SK<\/code>: <code>ORDER#<OrderID><\/code><br \/>\n    *   <code>Type<\/code>: <code>ORDER<\/code><br \/>\n    *   <code>SiparisTarihi<\/code>: &#8220;2023-10-27T10:00:00Z&#8221;, <code>Durum<\/code>: &#8220;Onayland\u0131&#8221;, <code>ToplamTutar<\/code>: 150.75<br \/>\n    *   <code>GSI1PK<\/code>: <code>ORDER_STATUS#Onayland\u0131<\/code><br \/>\n    *   <code>GSI1SK<\/code>: <code>2023-10-27T10:00:00Z#<OrderID><\/code><br \/>\n*   <strong>\u00dcr\u00fcn (PRODUCT) \u0130ncelemesi:<\/strong><br \/>\n    *   <code>PK<\/code>: <code>PRODUCT#<ProductID><\/code><br \/>\n    *   <code>SK<\/code>: <code>REVIEW#<UserID><\/code><br \/>\n    *   <code>Type<\/code>: <code>REVIEW<\/code><br \/>\n    *   <code>Puan<\/code>: 5, <code>Yorum<\/code>: &#8220;Harika bir \u00fcr\u00fcn!&#8221;, <code>Tarih<\/code>: &#8220;2023-10-26&#8221;<br \/>\n    *   <code>GSI1PK<\/code>: <code>USER#<UserID><\/code> (Kullan\u0131c\u0131n\u0131n t\u00fcm incelemelerini getirmek i\u00e7in)<br \/>\n    *   <code>GSI1SK<\/code>: <code>REVIEW#<ProductID>#<Tarih><\/code><\/p>\n<p>Bu yap\u0131 sayesinde:<br \/>\n*   Bir kullan\u0131c\u0131n\u0131n profilini ve t\u00fcm sipari\u015flerini tek bir <code>Query<\/code> i\u015flemiyle (<code>PK = USER#<UserID><\/code>, <code>SK begins_with \"PROFILE#\" OR SK begins_with \"ORDER#\"<\/code>) alabilirsiniz.<br \/>\n*   T\u00fcm onaylanm\u0131\u015f sipari\u015fleri <code>GSI1<\/code> \u00fczerinden sorgulayabilirsiniz (<code>GSI1PK = ORDER_STATUS#Onayland\u0131<\/code>).<\/p>\n<div class=\"code-example\">\n<pre><code class=\"language-javascript\">const AWS = require(&#039;aws-sdk&#039;);\n  const ddb = new AWS.DynamoDB.DocumentClient({ region: &#039;your-region&#039; });\n\n  \/\/ Tek tabloya kullan\u0131c\u0131 ve sipari\u015f ekleme \u00f6rne\u011fi\n  async function addUserData() {\n    const params = {\n      TableName: &#039;YourSingleTable&#039;,\n      Item: {\n        PK: &#039;USER#123&#039;,\n        SK: &#039;PROFILE#123&#039;,\n        Type: &#039;USER&#039;,\n        Name: &#039;Ahmet Can&#039;,\n        Email: &#039;ahmet@example.com&#039;,\n        CreatedAt: new Date().toISOString()\n      }\n    };\n    await ddb.put(params).promise();\n\n    const orderParams = {\n      TableName: &#039;YourSingleTable&#039;,\n      Item: {\n        PK: &#039;USER#123&#039;,\n        SK: &#039;ORDER#ORD-001&#039;,\n        Type: &#039;ORDER&#039;,\n        OrderId: &#039;ORD-001&#039;,\n        OrderDate: new Date().toISOString(),\n        Status: &#039;Pending&#039;,\n        TotalAmount: 250.00,\n        GSI1PK: &#039;ORDER_STATUS#Pending&#039;,\n        GSI1SK: new Date().toISOString() + &#039;#ORD-001&#039; \/\/ SK for GSI can be composite\n      }\n    };\n    await ddb.put(orderParams).promise();\n    console.log(\"Kullan\u0131c\u0131 ve sipari\u015f verileri ba\u015far\u0131yla eklendi.\");\n  }\n\n  \/\/ Bir kullan\u0131c\u0131n\u0131n profilini ve sipari\u015flerini getirme\n  async function getUserAndOrders(userId) {\n    const params = {\n      TableName: &#039;YourSingleTable&#039;,\n      KeyConditionExpression: &#039;PK = :pk AND begins_with(SK, :skPrefix)&#039;,\n      ExpressionAttributeValues: {\n        &#039;:pk&#039;: <code>USER#${userId}<\/code>,\n        &#039;:skPrefix&#039;: &#039;PROFILE#&#039; \/\/ or &#039;ORDER#&#039; to get only orders, or &#039;USER#&#039; to get all\n      }\n    };\n    const { Items } = await ddb.query(params).promise();\n    console.log(<code>Kullan\u0131c\u0131 ${userId} i\u00e7in veriler:<\/code>, Items);\n  }\n\n  \/\/ T\u00fcm bekleyen sipari\u015fleri GSI \u00fczerinden getirme\n  async function getPendingOrders() {\n    const params = {\n      TableName: &#039;YourSingleTable&#039;,\n      IndexName: &#039;GSI1&#039;, \/\/ Assuming your GSI is named GSI1\n      KeyConditionExpression: &#039;GSI1PK = :gsi1pk&#039;,\n      ExpressionAttributeValues: {\n        &#039;:gsi1pk&#039;: &#039;ORDER_STATUS#Pending&#039;\n      }\n    };\n    const { Items } = await ddb.query(params).promise();\n    console.log(\"Bekleyen Sipari\u015fler (GSI1 \u00fczerinden):\", Items);\n  }\n\n  \/\/ addUserData();\n  \/\/ getUserAndOrders(&#039;123&#039;);\n  \/\/ getPendingOrders();<\/pre>\n<p><\/code>\n<\/div>\n<p>Tek tablo tasar\u0131m\u0131, ilk ba\u015fta \u00f6\u011frenme e\u011frisine sahip olsa da, DynamoDB'nin tam potansiyelini a\u00e7\u0131\u011fa \u00e7\u0131kararak uygulaman\u0131z i\u00e7in inan\u0131lmaz bir performans ve maliyet avantaj\u0131 sa\u011flayabilir. Bu yakla\u015f\u0131m, DynamoDB'nin do\u011fas\u0131na en uygun modelleme \u015feklidir ve ileri d\u00fczey modellemenin temelini olu\u015fturur.<\/p>\n<h2>Karma\u015f\u0131k Eri\u015fim Desenlerini Y\u00f6netmek: Global Secondary Index'ler (GSI'lar) ile Esnek Sorgulama Nas\u0131l Sa\u011flan\u0131r?<\/h2>\n<p>DynamoDB'nin tek tablo tasar\u0131m\u0131n\u0131n g\u00fcc\u00fcn\u00fc anlam\u0131\u015f olsak da, ger\u00e7ek d\u00fcnya uygulamalar\u0131 genellikle birincil anahtarla do\u011frudan e\u015fle\u015fmeyen, \u00e7ok \u00e7e\u015fitli ve karma\u015f\u0131k eri\u015fim desenlerine sahiptir. \u0130\u015fte bu noktada Global Secondary Index'ler (GSI'lar), veri modellemenizin esnekli\u011fini ve sorgulama yeteneklerini muazzam bir \u015fekilde art\u0131ran kritik bir rol oynar. GSI'lar, ana tablonuzdaki veriler \u00fczerinde farkl\u0131 bir \"g\u00f6r\u00fcn\u00fcm\" sunarak, birincil anahtar\u0131n\u0131zdan farkl\u0131 bir Partition Key ve Sort Key kullanarak sorgulama yapman\u0131z\u0131 sa\u011flar. Bu sayede, uygulaman\u0131z\u0131n farkl\u0131 mod\u00fclleri veya kullan\u0131c\u0131 aray\u00fczleri, ayn\u0131 veriye farkl\u0131 kriterlere g\u00f6re eri\u015febilir.<\/p>\n<p><strong>GSI'lar Neden Bu Kadar \u00d6nemli?<\/strong><\/p>\n<p>Ana tablonuzdaki Partition Key ve Sort Key kombinasyonu, yaln\u0131zca belirli bir eri\u015fim deseni (\u00f6rne\u011fin, <code>UserID<\/code> ile belirli bir kullan\u0131c\u0131n\u0131n t\u00fcm verilerini getirme) i\u00e7in optimize edilmi\u015ftir. Ancak, \"t\u00fcm aktif sipari\u015fleri listele\", \"belirli bir tarihten sonraki t\u00fcm \u00fcr\u00fcn incelemelerini bul\" veya \"en \u00e7ok satan \u00fcr\u00fcnleri kategorisine g\u00f6re s\u0131rala\" gibi sorulara yan\u0131t vermek i\u00e7in farkl\u0131 anahtarlara ihtiyac\u0131n\u0131z vard\u0131r. GSI'lar, bu farkl\u0131 sorgu ihtiya\u00e7lar\u0131n\u0131 kar\u015f\u0131lamak i\u00e7in devreye girer.<\/p>\n<p>*   <strong>Esnek Sorgulama Yetenekleri:<\/strong> GSI'lar, ana tablonun birincil anahtar k\u0131s\u0131tlamalar\u0131ndan ba\u011f\u0131ms\u0131z olarak sorgulama yapman\u0131z\u0131 sa\u011flar. Kendi Partition Key ve iste\u011fe ba\u011fl\u0131 Sort Key'ine sahip olduklar\u0131 i\u00e7in, verilerinizi farkl\u0131 bir boyutta organize etmenize imkan tan\u0131rlar.<br \/>\n*   <strong>Paralel Eri\u015fim Desenleri:<\/strong> Her GSI, kendi okuma\/yazma kapasite birimlerine (RCU\/WCU) sahip olabilir. Bu, ana tablodan farkl\u0131 olarak, yo\u011fun sorgu alan bir GSI'\u0131n ana tablonun performans\u0131n\u0131 etkilememesini sa\u011flar. \u00d6rne\u011fin, raporlama i\u00e7in kullan\u0131lan bir GSI, canl\u0131 uygulama i\u00e7in kullan\u0131lan ana tablodan ayr\u0131 olarak \u00f6l\u00e7eklenebilir.<br \/>\n*   <strong>Seyrek Dizinler (Sparse Indexes):<\/strong> GSI'lar, sadece belirli niteliklere sahip \u00f6\u011felerin dizine dahil edilmesini sa\u011flayarak seyrek dizinler olu\u015fturabilir. E\u011fer bir \u00f6\u011fede GSI'\u0131n Partition Key veya Sort Key niteli\u011fi yoksa, bu \u00f6\u011fe dizine dahil edilmez. Bu, \u00f6zellikle b\u00fcy\u00fck tablolarda, yaln\u0131zca belirli bir alt k\u00fcmedeki verileri sorgulamak istedi\u011finizde \u00e7ok verimlidir. \u00d6rne\u011fin, sadece \"aktif\" durumdaki kullan\u0131c\u0131lar\u0131 listelemek i\u00e7in, <code>Status<\/code> niteli\u011fi \"aktif\" olan \u00f6\u011feler i\u00e7in bir GSI olu\u015fturabilirsiniz.<\/p>\n<p><strong>GSI ve LSI Aras\u0131ndaki Fark Nedir?<\/strong><\/p>\n<p>Kar\u0131\u015f\u0131kl\u0131k ya\u015fayanlar i\u00e7in bu ayr\u0131m\u0131 netle\u015ftirmek \u00f6nemlidir:<br \/>\n*   <strong>Global Secondary Index (GSI):<\/strong><br \/>\n    *   Ana tablonun Partition Key'inden <strong>farkl\u0131<\/strong> bir Partition Key'e sahip olabilir.<br \/>\n    *   Tamamen ba\u011f\u0131ms\u0131z okuma\/yazma kapasitesine sahiptir.<br \/>\n    *   Ana tablonun t\u00fcm verilerini veya bir alt k\u00fcmesini i\u00e7erebilir (projected attributes).<br \/>\n    *   Veriler ana tabloyla \"eventually consistent\" (nihai tutarl\u0131) olur, yani anl\u0131k g\u00fcncellemeler gecikmeli yans\u0131yabilir.<br \/>\n*   <strong>Local Secondary Index (LSI):<\/strong><br \/>\n    *   Ana tablonun Partition Key'iyle <strong>ayn\u0131<\/strong> Partition Key'e sahip olmak zorundad\u0131r.<br \/>\n    *   Farkl\u0131 bir Sort Key'e sahip olmal\u0131d\u0131r.<br \/>\n    *   Ana tablonun okuma\/yazma kapasitesini kullan\u0131r.<br \/>\n    *   Veriler ana tabloyla \"strongly consistent\" (g\u00fc\u00e7l\u00fc tutarl\u0131) olur.<br \/>\n    *   Tablo olu\u015fturulurken tan\u0131mlanmal\u0131 ve sonradan eklenemez.<\/p>\n<p><strong>Vaka Analizi: Sosyal Medya Uygulamas\u0131nda G\u00f6nderiler ve Etiketler<\/strong><\/p>\n<p>Bir sosyal medya uygulamas\u0131nda kullan\u0131c\u0131lar g\u00f6nderiler payla\u015f\u0131r ve bu g\u00f6nderilere etiketler ekleyebilir.<br \/>\nAna tablo yap\u0131s\u0131 \u015f\u00f6yle olabilir:<br \/>\n*   <code>PK<\/code>: <code>USER#<UserID><\/code><br \/>\n*   <code>SK<\/code>: <code>POST#<Timestamp>#<PostID><\/code><br \/>\n*   <code>Type<\/code>: <code>POST<\/code><br \/>\n*   <code>Content<\/code>: \"Merhaba D\u00fcnya!\", <code>Tags<\/code>: [\"#AWS\", \"#DynamoDB\"]<\/p>\n<p><strong>Eri\u015fim Desenleri:<\/strong><br \/>\n1.  Bir kullan\u0131c\u0131n\u0131n t\u00fcm g\u00f6nderilerini zaman s\u0131ras\u0131na g\u00f6re getir. (Ana tablo: <code>PK=USER#<UserID><\/code>, <code>SK begins_with \"POST#\"<\/code>)<br \/>\n2.  T\u00fcm g\u00f6nderileri etiketine g\u00f6re getir (\u00f6rne\u011fin, t\u00fcm \"#AWS\" etiketli g\u00f6nderiler). (Bu, ana tabloyla do\u011frudan m\u00fcmk\u00fcn de\u011fil.)<br \/>\n3.  En son g\u00f6nderilen t\u00fcm g\u00f6nderileri getir (t\u00fcm kullan\u0131c\u0131lardan). (Bu da ana tabloyla do\u011frudan m\u00fcmk\u00fcn de\u011fil.)<\/p>\n<p>Bu karma\u015f\u0131k eri\u015fim desenleri i\u00e7in GSI'lara ihtiyac\u0131m\u0131z var:<\/p>\n<p><strong>GSI 1: Etiketlere G\u00f6re G\u00f6nderiler<\/strong><br \/>\n*   <code>IndexName<\/code>: <code>PostsByTag<\/code><br \/>\n*   <code>GSI1PK<\/code>: <code>TAG#<TagIsmi><\/code><br \/>\n*   <code>GSI1SK<\/code>: <code>POST#<Timestamp>#<PostID><\/code><br \/>\n*   <code>Projected Attributes<\/code>: <code>ALL<\/code> (veya ihtiya\u00e7 duyulanlar)<\/p>\n<p>Bu GSI ile, belirli bir etikete (<code>TAG#AWS<\/code>) sahip t\u00fcm g\u00f6nderileri zaman s\u0131ras\u0131na g\u00f6re sorgulayabiliriz.<\/p>\n<p><strong>GSI 2: T\u00fcm G\u00f6nderiler (En Yeniye G\u00f6re)<\/strong><br \/>\n*   <code>IndexName<\/code>: <code>LatestPosts<\/code><br \/>\n*   <code>GSI2PK<\/code>: <code>ALL_POSTS<\/code> (Sabit bir de\u011fer, t\u00fcm g\u00f6nderileri tek bir partition'a toplar)<br \/>\n*   <code>GSI2SK<\/code>: <code>POST#<Timestamp>#<PostID><\/code> (Ters s\u0131ralama i\u00e7in <code>ScanIndexForward: false<\/code> kullan\u0131labilir)<br \/>\n*   <code>Projected Attributes<\/code>: <code>ALL<\/code><\/p>\n<p>Bu GSI ile, t\u00fcm g\u00f6nderileri en yeni olandan en eskiye do\u011fru sorgulayabiliriz. <code>ALL_POSTS<\/code> gibi sabit bir de\u011ferin GSI Partition Key olarak kullan\u0131lmas\u0131, t\u00fcm verilerin tek bir partition'a y\u0131\u011f\u0131lmas\u0131 riskini ta\u015f\u0131r. E\u011fer bu GSI'a gelen istek hacmi \u00e7ok y\u00fcksek olacaksa, bu tasar\u0131m dikkatli kullan\u0131lmal\u0131 veya daha fazla partition'a yaymak i\u00e7in farkl\u0131 stratejiler d\u00fc\u015f\u00fcn\u00fclmelidir (\u00f6rne\u011fin, tarih bazl\u0131 prefix eklemek).<\/p>\n<div class=\"code-example\">\n<pre><code class=\"language-javascript\">const AWS = require(&#039;aws-sdk&#039;);\n  const ddb = new AWS.DynamoDB.DocumentClient({ region: &#039;your-region&#039; });\n\n  \/\/ GSI ile bir etikete g\u00f6re g\u00f6nderi sorgulama \u00f6rne\u011fi\n  async function getPostsByTag(tag) {\n    const params = {\n      TableName: &#039;YourSocialMediaTable&#039;,\n      IndexName: &#039;PostsByTag&#039;, \/\/ GSI&#039;\u0131n ad\u0131\n      KeyConditionExpression: &#039;GSI1PK = :gsi1pk&#039;,\n      ExpressionAttributeValues: {\n        &#039;:gsi1pk&#039;: <code>TAG#${tag}<\/code>\n      },\n      ScanIndexForward: false \/\/ En yeni g\u00f6nderileri en \u00f6nce getirmek i\u00e7in\n    };\n    const { Items } = await ddb.query(params).promise();\n    console.log(<code>&#039;${tag}&#039; etiketine sahip g\u00f6nderiler:<\/code>, Items);\n  }\n\n  \/\/ T\u00fcm en yeni g\u00f6nderileri getirme \u00f6rne\u011fi\n  async function getLatestPosts() {\n    const params = {\n      TableName: &#039;YourSocialMediaTable&#039;,\n      IndexName: &#039;LatestPosts&#039;, \/\/ Di\u011fer GSI&#039;\u0131n ad\u0131\n      KeyConditionExpression: &#039;GSI2PK = :gsi2pk&#039;,\n      ExpressionAttributeValues: {\n        &#039;:gsi2pk&#039;: &#039;ALL_POSTS&#039;\n      },\n      ScanIndexForward: false, \/\/ En yeni g\u00f6nderileri en \u00f6nce getirmek i\u00e7in\n      Limit: 10 \/\/ Sadece ilk 10 g\u00f6nderiyi al\n    };\n    const { Items } = await ddb.query(params).promise();\n    console.log(\"En yeni 10 g\u00f6nderi:\", Items);\n  }\n\n  \/\/ getPostsByTag(&#039;AWS&#039;);\n  \/\/ getLatestPosts();<\/pre>\n<p><\/code>\n<\/div>\n<p>GSI'lar, DynamoDB veri modellemesinde neredeyse her zaman kullan\u0131lan ve karma\u015f\u0131k eri\u015fim desenlerini basit, h\u0131zl\u0131 ve maliyet etkin bir \u015fekilde \u00e7\u00f6zmenizi sa\u011flayan temel bir ara\u00e7t\u0131r. Do\u011fru GSI tasar\u0131m\u0131, uygulaman\u0131z\u0131n performans\u0131n\u0131 ve \u00f6l\u00e7eklenebilirli\u011fini do\u011frudan etkiler. Bu y\u00fczden, veri modelleme s\u00fcrecinin ba\u015f\u0131ndan itibaren hangi eri\u015fim desenlerinin GSI gerektirece\u011fini dikkatlice analiz etmek \u00f6nemlidir.<\/p>\n<h2>Geli\u015fmi\u015f Veri Yap\u0131lar\u0131 ve Desenler: Denormalizasyon ve Sparse Index'ler Performans\u0131 Art\u0131ran S\u0131rlar Nelerdir?<\/h2>\n<p>DynamoDB ile veri modellemede, geleneksel ili\u015fkisel veritaban\u0131 d\u00fc\u015f\u00fcnce yap\u0131s\u0131ndan uzakla\u015fmak ve performans\u0131 en \u00fcst d\u00fczeye \u00e7\u0131karmak i\u00e7in baz\u0131 ileri d\u00fczey desenleri benimsemek gerekir. Bu desenlerin ba\u015f\u0131nda denormalizasyon ve Sparse Index'lerin ak\u0131ll\u0131ca kullan\u0131m\u0131 gelir. Bu yakla\u015f\u0131mlar, \u00f6zellikle y\u00fcksek okuma performans\u0131n\u0131n kritik oldu\u011fu senaryolarda uygulaman\u0131z\u0131n h\u0131z\u0131n\u0131 ve maliyet etkinli\u011fini \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131rabilir.<\/p>\n<p><strong>Denormalizasyon: Okuma Performans\u0131n\u0131n Anahtar\u0131<\/strong><\/p>\n<p>\u0130li\u015fkisel veritabanlar\u0131nda \"Normalizasyon\", veri tekrar\u0131n\u0131 en aza indirerek veri b\u00fct\u00fcnl\u00fc\u011f\u00fcn\u00fc sa\u011flamak ve depolama alan\u0131ndan tasarruf etmek i\u00e7in \u00f6nemlidir. Ancak bu, birden fazla tabloyu birle\u015ftirmeyi (JOIN) gerektirdi\u011finden okuma performans\u0131n\u0131 d\u00fc\u015f\u00fcrebilir. DynamoDB gibi NoSQL veritabanlar\u0131nda ise, JOIN i\u015flemleri genellikle yoktur veya \u00e7ok s\u0131n\u0131rl\u0131d\u0131r. Bu nedenle, DynamoDB'de denormalizasyon, yani ilgili verileri birden fazla yerde kopyalayarak saklamak, temel bir performans optimizasyon tekni\u011fidir.<\/p>\n<p><strong>Neden Denormalizasyon?<\/strong><br \/>\n*   <strong>Tek Okuma \u0130\u015flemi:<\/strong> \u0130htiyac\u0131n\u0131z olan t\u00fcm verileri tek bir DynamoDB \u00f6\u011fesi i\u00e7inde veya tek bir Partition Key sorgusunda toplayarak, birden fazla a\u011f \u00e7a\u011fr\u0131s\u0131 yapmaktan ka\u00e7\u0131n\u0131rs\u0131n\u0131z. Bu, gecikmeyi (latency) \u00f6nemli \u00f6l\u00e7\u00fcde azalt\u0131r.<br \/>\n*   <strong>Basitle\u015ftirilmi\u015f Uygulama Mant\u0131\u011f\u0131:<\/strong> Uygulama katman\u0131nda karma\u015f\u0131k birle\u015ftirme (join) veya birden fazla sorgu yapma ihtiyac\u0131n\u0131 ortadan kald\u0131r\u0131r.<br \/>\n*   <strong>Maliyet Azaltma:<\/strong> Daha az sorgu, daha az okuma kapasitesi birimi (RCU) t\u00fcketimi anlam\u0131na gelir.<\/p>\n<p><strong>Denormalizasyon Ne Zaman Kullan\u0131l\u0131r?<\/strong><br \/>\n*   <strong>S\u0131k Birlikte Eri\u015filen Veriler:<\/strong> Bir \u00f6\u011fe her sorguland\u0131\u011f\u0131nda, onunla ilgili ba\u015fka bir \u00f6\u011fenin de neredeyse her zaman sorgulanmas\u0131 gerekiyorsa. \u00d6rne\u011fin, bir <code>Kullanici<\/code> profili ve onun son <code>10 Sipari\u015f<\/code> verisi her zaman birlikte g\u00f6steriliyorsa, bunlar\u0131 ayn\u0131 Partition Key alt\u0131nda depolamak veya kullan\u0131c\u0131n\u0131n profil \u00f6\u011fesi i\u00e7inde son sipari\u015f \u00f6zetlerini denormalize etmek mant\u0131kl\u0131d\u0131r.<br \/>\n*   <strong>Az G\u00fcncellenen, \u00c7ok Okunan Veriler:<\/strong> Referans veriler (\u00f6rne\u011fin, \u00fcr\u00fcn kategorileri, d\u00f6viz kurlar\u0131) gibi nadiren de\u011fi\u015fen ancak s\u0131k s\u0131k okunan veriler i\u00e7in denormalizasyon uygundur.<\/p>\n<p><strong>Denormalizasyonun Dezavantaj\u0131:<\/strong> Veri tekrar\u0131, g\u00fcncellemeleri daha karma\u015f\u0131k hale getirebilir. Bir denormalize edilmi\u015f veri de\u011fi\u015fti\u011finde, kopyaland\u0131\u011f\u0131 t\u00fcm yerlerde g\u00fcncellenmesi gerekir. Bu genellikle lambda fonksiyonlar\u0131 veya DynamoDB Streams kullan\u0131larak otomatikle\u015ftirilir.<\/p>\n<p><strong>Sparse Index'ler: Hedefli Sorgulama \u0130\u00e7in G\u00fc\u00e7l\u00fc Bir Ara\u00e7<\/strong><\/p>\n<p>Daha \u00f6nce GSI'lar\u0131 tart\u0131\u015f\u0131rken bahsetti\u011fimiz bir alt kavram olan Sparse Index'ler, belirli bir ihtiyaca y\u00f6nelik olarak olu\u015fturulmu\u015f, olduk\u00e7a verimli bir GSI t\u00fcr\u00fcd\u00fcr. Bir GSI, ana tablodaki t\u00fcm \u00f6\u011feleri veya yaln\u0131zca belirli niteliklere sahip \u00f6\u011feleri dizine ekleyebilir. E\u011fer bir \u00f6\u011fede GSI'\u0131n Partition Key veya Sort Key niteli\u011fi yoksa, o \u00f6\u011fe dizine dahil edilmez. Bu \u00f6zelli\u011fi kullanarak \"seyrek\" yani \"sparse\" dizinler olu\u015ftururuz.<\/p>\n<p><strong>Neden Sparse Index'ler?<\/strong><br \/>\n*   <strong>Hedefli Sorgulama:<\/strong> Yaln\u0131zca belirli bir ko\u015fulu kar\u015f\u0131layan \u00f6\u011feleri sorgulamak istedi\u011finizde, dizini gereksiz verilerle doldurmaktan ka\u00e7\u0131n\u0131r. Bu, dizin boyutunu k\u00fc\u00e7\u00fclt\u00fcr ve sorgu performans\u0131n\u0131 art\u0131r\u0131r.<br \/>\n*   <strong>Maliyet Optimizasyonu:<\/strong> Daha k\u00fc\u00e7\u00fck dizinler, daha az depolama maliyeti ve daha h\u0131zl\u0131 dizin g\u00fcncellemeleri anlam\u0131na gelir. Ayr\u0131ca, sorgular\u0131n\u0131z\u0131n taranmas\u0131 gereken \u00f6\u011fe say\u0131s\u0131n\u0131 azaltt\u0131\u011f\u0131 i\u00e7in okuma kapasitesi birimlerinden tasarruf sa\u011flar.<br \/>\n*   <strong>\"Flag\" Bazl\u0131 Sorgular:<\/strong> Bir \u00f6\u011fenin belirli bir duruma (\u00f6rne\u011fin, \"aktive edildi\", \"yay\u0131nda\", \"ar\u015fivlendi\") sahip olup olmad\u0131\u011f\u0131n\u0131 sorgulamak i\u00e7in idealdir.<\/p>\n<p><strong>Sparse Index Nas\u0131l Olu\u015fturulur?<\/strong><br \/>\nGSI tan\u0131m\u0131n\u0131zda, yaln\u0131zca belirli bir niteli\u011fin mevcut oldu\u011fu \u00f6\u011feleri dizine dahil edecek \u015fekilde Partition Key veya Sort Key olarak o niteli\u011fi kullan\u0131rs\u0131n\u0131z.<\/p>\n<p><strong>Vaka Analizi: \u00c7ok Seviyeli Bir Men\u00fc Sistemi<\/strong><\/p>\n<p>Bir SaaS platformunda, kullan\u0131c\u0131lar\u0131n kendilerine \u00f6zel \u00e7ok seviyeli men\u00fcleri y\u00f6netti\u011fini d\u00fc\u015f\u00fcnelim. Her men\u00fc \u00f6\u011fesi (Menu Item), bir \u00fcst \u00f6\u011feye (Parent Item) sahip olabilir ve belirli bir <code>Durum<\/code>'a (Aktif\/Pasif) sahip olabilir.<\/p>\n<p>Ana tablo yap\u0131s\u0131 (tek tablo tasar\u0131m\u0131 kullanarak):<br \/>\n*   <code>PK<\/code>: <code>TENANT#<TenantID><\/code> (Kirac\u0131lar aras\u0131 izolasyon)<br \/>\n*   <code>SK<\/code>: <code>MENUITEM#<MenuItemID><\/code><br \/>\n*   <code>Type<\/code>: <code>MENU_ITEM<\/code><br \/>\n*   <code>Title<\/code>: \"Ayarlar\", <code>ParentID<\/code>: \"null\", <code>Status<\/code>: \"ACTIVE\"<br \/>\n*   <code>ParentSK<\/code>: <code>MENUITEM#<ParentItemID><\/code> (Alt \u00f6\u011fe i\u00e7in)<\/p>\n<p><strong>Eri\u015fim Desenleri:<\/strong><br \/>\n1.  Bir kirac\u0131n\u0131n t\u00fcm men\u00fc \u00f6\u011felerini getir. (Ana tablo: <code>PK=TENANT#<TenantID><\/code>, <code>SK begins_with \"MENUITEM#\"<\/code>)<br \/>\n2.  Bir kirac\u0131n\u0131n yaln\u0131zca <strong>aktif<\/strong> men\u00fc \u00f6\u011felerini getir. (Bu, do\u011frudan ana tabloyla etkili de\u011fil, bir <code>FilterExpression<\/code> t\u00fcm \u00f6\u011feleri tarayaca\u011f\u0131ndan verimsiz olur.)<br \/>\n3.  Bir kirac\u0131n\u0131n belirli bir \u00fcst men\u00fc \u00f6\u011fesine ait t\u00fcm alt men\u00fc \u00f6\u011felerini getir.<\/p>\n<p><strong>Sparse Index ve Denormalizasyon \u00c7\u00f6z\u00fcm\u00fc:<\/strong><\/p>\n<p><strong>1. Aktif Men\u00fc \u00d6\u011feleri i\u00e7in Sparse GSI:<\/strong><br \/>\nSadece <code>Status<\/code> niteli\u011fi \"ACTIVE\" olan men\u00fc \u00f6\u011felerini i\u00e7eren bir GSI tan\u0131mlayal\u0131m:<br \/>\n*   <code>IndexName<\/code>: <code>ActiveMenuItems<\/code><br \/>\n*   <code>GSI1PK<\/code>: <code>TENANT#<TenantID>#ACTIVE<\/code> (Burada Sparse Index'i olu\u015fturmak i\u00e7in <code>ACTIVE<\/code> flag'ini ekliyoruz)<br \/>\n*   <code>GSI1SK<\/code>: <code>MENUITEM#<MenuItemID><\/code><br \/>\n*   <code>Projected Attributes<\/code>: <code>Title<\/code>, <code>ParentID<\/code>, <code>Status<\/code> (veya ihtiya\u00e7 duyulanlar)<\/p>\n<p>Bu GSI'a sadece <code>Status: \"ACTIVE\"<\/code> olan \u00f6\u011feler eklenecektir. B\u00f6ylece, bir kirac\u0131n\u0131n yaln\u0131zca aktif men\u00fc \u00f6\u011felerini getirmek i\u00e7in <code>GSI1PK = TENANT#<TenantID>#ACTIVE<\/code> \u015feklinde sorgulayabiliriz. Bu, t\u00fcm men\u00fc \u00f6\u011felerini taramaktan \u00e7ok daha verimlidir.<\/p>\n<p><strong>2. Alt Men\u00fc \u00d6\u011feleri \u0130\u00e7in Denormalizasyon ve Composite Sort Key:<\/strong><br \/>\nBir kirac\u0131n\u0131n belirli bir \u00fcst \u00f6\u011fesine ait alt \u00f6\u011felerini h\u0131zl\u0131ca getirmek i\u00e7in <code>SK<\/code>'yi veya bir GSI'\u0131n <code>SK<\/code>'sini kompozit hale getirebiliriz:<br \/>\n*   Mevcut <code>SK<\/code> yeterli de\u011filse ( <code>MENUITEM#<MenuItemID><\/code> ):<br \/>\n    *   Bir GSI tan\u0131mlayabiliriz:<br \/>\n        *   <code>IndexName<\/code>: <code>MenuItemsByParent<\/code><br \/>\n        *   <code>GSI2PK<\/code>: <code>TENANT#<TenantID>#PARENT#<ParentItemID><\/code><br \/>\n        *   <code>GSI2SK<\/code>: <code>MENUITEM#<MenuItemID><\/code><br \/>\n    Bu GSI ile, <code>GSI2PK = TENANT#<TenantID>#PARENT#<ParentItemID><\/code> \u015feklinde sorgulayarak bir \u00fcst \u00f6\u011fenin t\u00fcm alt \u00f6\u011felerini getirebiliriz. <code>ParentID<\/code> niteli\u011fi olmayan \u00f6\u011feler bu GSI'a dahil edilmeyece\u011finden, bu da bir t\u00fcr seyrek dizin g\u00f6revi g\u00f6r\u00fcr.<\/p>\n<div class=\"code-example\">\n<pre><code class=\"language-javascript\">const AWS = require(&#039;aws-sdk&#039;);\n  const ddb = new AWS.DynamoDB.DocumentClient({ region: &#039;your-region&#039; });\n\n  \/\/ Men\u00fc \u00f6\u011fesi ekleme \u00f6rne\u011fi\n  async function addMenuItem(tenantId, itemId, title, parentId, status) {\n    const item = {\n      PK: <code>TENANT#${tenantId}<\/code>,\n      SK: <code>MENUITEM#${itemId}<\/code>,\n      Type: &#039;MENU_ITEM&#039;,\n      Title: title,\n      Status: status\n    };\n    if (parentId) {\n      item.ParentID = parentId;\n      \/\/ GSI2PK i\u00e7in gerekli\n      item.GSI2PK = <code>TENANT#${tenantId}#PARENT#${parentId}<\/code>;\n      item.GSI2SK = <code>MENUITEM#${itemId}<\/code>;\n    }\n    if (status === &#039;ACTIVE&#039;) {\n      \/\/ Sparse GSI i\u00e7in gerekli\n      item.GSI1PK = <code>TENANT#${tenantId}#ACTIVE<\/code>;\n      item.GSI1SK = <code>MENUITEM#${itemId}<\/code>;\n    }\n\n    const params = {\n      TableName: &#039;YourMenuTable&#039;,\n      Item: item\n    };\n    await ddb.put(params).promise();\n    console.log(<code>Men\u00fc \u00f6\u011fesi ${itemId} ba\u015far\u0131yla eklendi.<\/code>);\n  }\n\n  \/\/ Aktif men\u00fc \u00f6\u011felerini Sparse GSI \u00fczerinden getirme\n  async function getActiveMenuItems(tenantId) {\n    const params = {\n      TableName: &#039;YourMenuTable&#039;,\n      IndexName: &#039;ActiveMenuItems&#039;, \/\/ GSI1&#039;\u0131n ad\u0131\n      KeyConditionExpression: &#039;GSI1PK = :gsi1pk&#039;,\n      ExpressionAttributeValues: {\n        &#039;:gsi1pk&#039;: <code>TENANT#${tenantId}#ACTIVE<\/code>\n      }\n    };\n    const { Items } = await ddb.query(params).promise();\n    console.log(<code>Kirac\u0131 ${tenantId} i\u00e7in aktif men\u00fc \u00f6\u011feleri:<\/code>, Items);\n  }\n\n  \/\/ Bir \u00fcst men\u00fc \u00f6\u011fesinin alt\u0131ndaki \u00f6\u011feleri GSI \u00fczerinden getirme\n  async function getSubMenuItems(tenantId, parentId) {\n    const params = {\n      TableName: &#039;YourMenuTable&#039;,\n      IndexName: &#039;MenuItemsByParent&#039;, \/\/ GSI2&#039;\u0131n ad\u0131\n      KeyConditionExpression: &#039;GSI2PK = :gsi2pk&#039;,\n      ExpressionAttributeValues: {\n        &#039;:gsi2pk&#039;: <code>TENANT#${tenantId}#PARENT#${parentId}<\/code>\n      }\n    };\n    const { Items } = await ddb.query(params).promise();\n    console.log(<code>Kirac\u0131 ${tenantId} ve \u00fcst \u00f6\u011fe ${parentId} i\u00e7in alt men\u00fc \u00f6\u011feleri:<\/code>, Items);\n  }\n\n  \/\/ addMenuItem(&#039;tenant1&#039;, &#039;item1&#039;, &#039;Anasayfa&#039;, null, &#039;ACTIVE&#039;);\n  \/\/ addMenuItem(&#039;tenant1&#039;, &#039;item2&#039;, &#039;Hakk\u0131m\u0131zda&#039;, &#039;item1&#039;, &#039;ACTIVE&#039;);\n  \/\/ addMenuItem(&#039;tenant1&#039;, &#039;item3&#039;, &#039;\u0130leti\u015fim&#039;, &#039;item1&#039;, &#039;INACTIVE&#039;);\n  \/\/ getActiveMenuItems(&#039;tenant1&#039;);\n  \/\/ getSubMenuItems(&#039;tenant1&#039;, &#039;item1&#039;);<\/pre>\n<p><\/code>\n<\/div>\n<p>Denormalizasyon ve Sparse Index'ler, DynamoDB veri modellemesinin ustal\u0131k gerektiren ancak b\u00fcy\u00fck faydalar sa\u011flayan iki \u00f6nemli desenidir. Bu teknikler, uygulaman\u0131z\u0131n performans kritik eri\u015fim desenlerini ele al\u0131rken, ayn\u0131 zamanda kaynak kullan\u0131m\u0131n\u0131 optimize etmenize ve maliyetleri d\u00fc\u015f\u00fcrmenize olanak tan\u0131r. Her zaman oldu\u011fu gibi, bu teknikleri uygularken uygulaman\u0131z\u0131n spesifik eri\u015fim desenlerini ve veri b\u00fcy\u00fcmesini dikkatlice analiz etmek, en uygun \u00e7\u00f6z\u00fcm\u00fc bulmak i\u00e7in anahtard\u0131r.<\/p>\n<h2>Vaka Analizi: B\u00fcy\u00fck \u00d6l\u00e7ekli Bir Uygulama \u0130\u00e7in DynamoDB Modeli - Bir SaaS Platformunun Veri Modeli Nas\u0131l Tasarland\u0131?<\/h2>\n<p>\u015eimdiye kadar ele ald\u0131\u011f\u0131m\u0131z tek tablo tasar\u0131m\u0131, GSI'lar, denormalizasyon ve Sparse Index'ler gibi ileri d\u00fczey teknikleri, ger\u00e7ek d\u00fcnya, b\u00fcy\u00fck \u00f6l\u00e7ekli bir SaaS (Software as a Service) platformu ba\u011flam\u0131nda bir araya getirelim. Hayalimizdeki SaaS platformu, birden fazla kirac\u0131ya (tenant) hizmet veriyor ve her kirac\u0131n\u0131n kendi kullan\u0131c\u0131lar\u0131, projeleri, g\u00f6revleri ve faturalama kay\u0131tlar\u0131 bulunuyor. Bu platform, y\u00fcksek performans, d\u00fc\u015f\u00fck gecikme ve maliyet etkinli\u011fi ile milyonlarca kullan\u0131c\u0131n\u0131n ayn\u0131 anda eri\u015fim sa\u011flayabilmesini hedefliyor.<\/p>\n<p><strong>SaaS Platformunun Temel Varl\u0131klar\u0131 ve Eri\u015fim Desenleri:<\/strong><\/p>\n<p>1.  <strong>Kirac\u0131 (Tenant):<\/strong><br \/>\n    *   Eri\u015fim Deseni: <code>TenantID<\/code> ile kirac\u0131 bilgilerini (ad\u0131, abonelik plan\u0131, ileti\u015fim) getir.<br \/>\n2.  <strong>Kullan\u0131c\u0131 (User):<\/strong> (Her kirac\u0131ya ait)<br \/>\n    *   Eri\u015fim Deseni 1: <code>TenantID<\/code> ve <code>UserID<\/code> ile belirli bir kullan\u0131c\u0131 profilini getir.<br \/>\n    *   Eri\u015fim Deseni 2: <code>TenantID<\/code> ile bir kirac\u0131ya ait t\u00fcm kullan\u0131c\u0131lar\u0131 listele.<br \/>\n    *   Eri\u015fim Deseni 3: <code>Email<\/code> ile kullan\u0131c\u0131y\u0131 bul (globally unique).<br \/>\n3.  <strong>Proje (Project):<\/strong> (Her kirac\u0131ya ait, kullan\u0131c\u0131lara atanabilir)<br \/>\n    *   Eri\u015fim Deseni 1: <code>TenantID<\/code> ve <code>ProjectID<\/code> ile belirli bir proje detay\u0131n\u0131 getir.<br \/>\n    *   Eri\u015fim Deseni 2: <code>TenantID<\/code> ile bir kirac\u0131ya ait t\u00fcm projeleri listele.<br \/>\n    *   Eri\u015fim Deseni 3: <code>TenantID<\/code> ve <code>UserID<\/code> ile bir kullan\u0131c\u0131ya atanm\u0131\u015f t\u00fcm projeleri listele.<br \/>\n4.  <strong>G\u00f6rev (Task):<\/strong> (Projelere ait, kullan\u0131c\u0131lara atanabilir)<br \/>\n    *   Eri\u015fim Deseni 1: <code>TenantID<\/code>, <code>ProjectID<\/code> ve <code>TaskID<\/code> ile belirli bir g\u00f6revi getir.<br \/>\n    *   Eri\u015fim Deseni 2: <code>TenantID<\/code> ve <code>ProjectID<\/code> ile bir projeye ait t\u00fcm g\u00f6revleri listele.<br \/>\n    *   Eri\u015fim Deseni 3: <code>TenantID<\/code>, <code>UserID<\/code> ve <code>Status<\/code> ile bir kullan\u0131c\u0131ya atanm\u0131\u015f ve belirli bir durumda (\u00f6rn. \"PENDING\") olan g\u00f6revleri listele.<br \/>\n    *   Eri\u015fim Deseni 4: <code>TenantID<\/code> ile t\u00fcm <code>OVERDUE<\/code> g\u00f6revleri listele.<br \/>\n5.  <strong>Fatura (Invoice):<\/strong> (Kirac\u0131lara ait)<br \/>\n    *   Eri\u015fim Deseni 1: <code>TenantID<\/code> ve <code>InvoiceID<\/code> ile belirli bir faturay\u0131 getir.<br \/>\n    *   Eri\u015fim Deseni 2: <code>TenantID<\/code> ile bir kirac\u0131n\u0131n t\u00fcm faturalar\u0131n\u0131 tarih s\u0131ras\u0131na g\u00f6re listele.<\/p>\n<p><strong>Tek Tablo Tasar\u0131m\u0131 Yakla\u015f\u0131m\u0131:<\/strong><\/p>\n<p>T\u00fcm bu varl\u0131klar\u0131 tek bir <code>SaaSPlatform<\/code> tablosunda tutaca\u011f\u0131z ve <code>PK<\/code>, <code>SK<\/code>, <code>Type<\/code> ile GSI'lar\u0131 kullanarak t\u00fcm eri\u015fim desenlerini destekleyece\u011fiz.<\/p>\n<p><strong>Tablo Yap\u0131s\u0131:<\/strong><\/p>\n<p>| Nitelik | A\u00e7\u0131klama |<br \/>\n| :------- | :-------- |<br \/>\n| <code>PK<\/code> | Partition Key (Tenant, User, Project, Task, Invoice ID'lerini i\u00e7erir) |<br \/>\n| <code>SK<\/code> | Sort Key (Varl\u0131k t\u00fcr\u00fc ve ID'lerini i\u00e7erir, s\u0131ralama sa\u011flar) |<br \/>\n| <code>Type<\/code> | Varl\u0131k tipini (TENANT, USER, PROJECT, TASK, INVOICE) belirtir |<br \/>\n| <code>Data<\/code> | Varl\u0131\u011fa \u00f6zg\u00fc JSON verisi (ad, a\u00e7\u0131klama, tarih, durum vb.) |<br \/>\n| <code>GSI1PK<\/code> | Global Secondary Index 1 Partition Key |<br \/>\n| <code>GSI1SK<\/code> | Global Secondary Index 1 Sort Key |<br \/>\n| <code>GSI2PK<\/code> | Global Secondary Index 2 Partition Key |<br \/>\n| <code>GSI2SK<\/code> | Global Secondary Index 2 Sort Key |<br \/>\n| <code>GSI3PK<\/code> | Global Secondary Index 3 Partition Key |<br \/>\n| <code>GSI3SK<\/code> | Global Secondary Index 3 Sort Key |<\/p>\n<p><strong>Veri Modelleme Detaylar\u0131:<\/strong><\/p>\n<p>1.  <strong>Kirac\u0131 (Tenant):<\/strong><br \/>\n    *   <code>PK<\/code>: <code>TENANT#<TenantID><\/code><br \/>\n    *   <code>SK<\/code>: <code>TENANT#<TenantID><\/code><br \/>\n    *   <code>Type<\/code>: <code>TENANT<\/code><br \/>\n    *   <code>Data<\/code>: <code>{ \"name\": \"ABC Corp\", \"plan\": \"Enterprise\" }<\/code><br \/>\n    *   *Eri\u015fim:* <code>PK = TENANT#<TenantID><\/code>, <code>SK = TENANT#<TenantID><\/code><\/p>\n<p>2.  <strong>Kullan\u0131c\u0131 (User):<\/strong><br \/>\n    *   <code>PK<\/code>: <code>TENANT#<TenantID><\/code><br \/>\n    *   <code>SK<\/code>: <code>USER#<UserID><\/code><br \/>\n    *   <code>Type<\/code>: <code>USER<\/code><br \/>\n    *   <code>Data<\/code>: <code>{ \"username\": \"jane.doe\", \"email\": \"jane@abc.com\" }<\/code><br \/>\n    *   <code>GSI1PK<\/code>: <code>USER_EMAIL#jane@abc.com<\/code> (Email ile kullan\u0131c\u0131 bulmak i\u00e7in)<br \/>\n    *   <code>GSI1SK<\/code>: <code>USER#<UserID><\/code> (Benzersizlik sa\u011flamak i\u00e7in)<br \/>\n    *   *Eri\u015fim 1:* <code>PK = TENANT#<TenantID><\/code>, <code>SK = USER#<UserID><\/code><br \/>\n    *   *Eri\u015fim 2:* <code>PK = TENANT#<TenantID><\/code>, <code>SK begins_with \"USER#\"<\/code><br \/>\n    *   *Eri\u015fim 3:* <code>GSI1PK = USER_EMAIL#jane@abc.com<\/code><\/p>\n<p>3.  <strong>Proje (Project):<\/strong><br \/>\n    *   <code>PK<\/code>: <code>TENANT#<TenantID><\/code><br \/>\n    *   <code>SK<\/code>: <code>PROJECT#<ProjectID><\/code><br \/>\n    *   <code>Type<\/code>: <code>PROJECT<\/code><br \/>\n    *   <code>Data<\/code>: <code>{ \"name\": \"Web Redesign\", \"status\": \"Active\", \"ownerId\": \"user123\" }<\/code><br \/>\n    *   <code>GSI2PK<\/code>: <code>TENANT#<TenantID>#USER#<OwnerUserID><\/code> (Kullan\u0131c\u0131n\u0131n projelerini listelemek i\u00e7in)<br \/>\n    *   <code>GSI2SK<\/code>: <code>PROJECT#<ProjectID><\/code><br \/>\n    *   *Eri\u015fim 1:* <code>PK = TENANT#<TenantID><\/code>, <code>SK = PROJECT#<ProjectID><\/code><br \/>\n    *   *Eri\u015fim 2:* <code>PK = TENANT#<TenantID><\/code>, <code>SK begins_with \"PROJECT#\"<\/code><br \/>\n    *   *Eri\u015fim 3:* <code>GSI2PK = TENANT#<TenantID>#USER#user123<\/code><\/p>\n<p>4.  <strong>G\u00f6rev (Task):<\/strong><br \/>\n    *   <code>PK<\/code>: <code>TENANT#<TenantID>#PROJECT#<ProjectID><\/code> (Proje baz\u0131nda g\u00f6revleri gruplamak i\u00e7in)<br \/>\n    *   <code>SK<\/code>: <code>TASK#<TaskID><\/code><br \/>\n    *   <code>Type<\/code>: <code>TASK<\/code><br \/>\n    *   <code>Data<\/code>: <code>{ \"title\": \"Implement Login\", \"status\": \"PENDING\", \"assignedTo\": \"user123\", \"dueDate\": \"2023-11-15\" }<\/code><br \/>\n    *   <code>GSI3PK<\/code>: <code>TENANT#<TenantID>#USER#<AssignedToUserID>#TASK_STATUS#<Status><\/code> (Kullan\u0131c\u0131n\u0131n belirli durumdaki g\u00f6revlerini listelemek i\u00e7in - Sparse Index olarak da kullan\u0131labilir)<br \/>\n    *   <code>GSI3SK<\/code>: <code>TASK#<DueDate>#<TaskID><\/code> (Tarihe g\u00f6re s\u0131ralamak i\u00e7in)<br \/>\n    *   <code>GSI1PK<\/code>: <code>TENANT#<TenantID>#TASK_OVERDUE<\/code> (Yaln\u0131zca s\u00fcresi ge\u00e7mi\u015f g\u00f6revler i\u00e7in Sparse Index) - E\u011fer <code>dueDate<\/code> > <code>now<\/code> ise bu nitelik eklenmez.<br \/>\n    *   <code>GSI1SK<\/code>: <code>TASK#<DueDate>#<TaskID><\/code><br \/>\n    *   *Eri\u015fim 1:* <code>PK = TENANT#<TenantID>#PROJECT#<ProjectID><\/code>, <code>SK = TASK#<TaskID><\/code><br \/>\n    *   *Eri\u015fim 2:* <code>PK = TENANT#<TenantID>#PROJECT#<ProjectID><\/code>, <code>SK begins_with \"TASK#\"<\/code><br \/>\n    *   *Eri\u015fim 3:* <code>GSI3PK = TENANT#<TenantID>#USER#user123#TASK_STATUS#PENDING<\/code><br \/>\n    *   *Eri\u015fim 4:* <code>GSI1PK = TENANT#<TenantID>#TASK_OVERDUE<\/code><\/p>\n<p>5.  <strong>Fatura (Invoice):<\/strong><br \/>\n    *   <code>PK<\/code>: <code>TENANT#<TenantID><\/code><br \/>\n    *   <code>SK<\/code>: <code>INVOICE#<InvoiceDate>#<InvoiceID><\/code> (Tarihe g\u00f6re s\u0131ralanm\u0131\u015f faturalar i\u00e7in)<br \/>\n    *   <code>Type<\/code>: <code>INVOICE<\/code><br \/>\n    *   <code>Data<\/code>: <code>{ \"amount\": 99.99, \"period\": \"Nov 2023\" }<\/code><br \/>\n    *   *Eri\u015fim 1:* <code>PK = TENANT#<TenantID><\/code>, <code>SK = INVOICE#<InvoiceDate>#<InvoiceID><\/code><br \/>\n    *   *Eri\u015fim 2:* <code>PK = TENANT#<TenantID><\/code>, <code>SK begins_with \"INVOICE#\"<\/code> (T\u00fcm faturalar tarih s\u0131ras\u0131na g\u00f6re)<\/p>\n<div class=\"tip-box\">\n  Uzman \u0130pucu: \u00c7oklu GSI'lar kullan\u0131rken, her GSI'\u0131n kendi RCU\/WCU maliyeti oldu\u011funu unutmay\u0131n. Gereksiz GSI'lardan ka\u00e7\u0131n\u0131n ve sadece kritik eri\u015fim desenleri i\u00e7in dizin olu\u015fturun. GSI'lar\u0131 \"sparse\" yaparak sadece ilgili veriyi dizine dahil etmek maliyet ve performans a\u00e7\u0131s\u0131ndan \u00e7ok \u00f6nemlidir.\n<\/div>\n<p><strong>Uygulama Mimarisi ve Veri Ak\u0131\u015f\u0131:<\/strong><\/p>\n<p>Bu modelde, uygulaman\u0131n farkl\u0131 servisleri (\u00f6rne\u011fin, kullan\u0131c\u0131 y\u00f6netimi servisi, proje servisi, faturalama servisi) ayn\u0131 DynamoDB tablosuna eri\u015fir ancak kendi varl\u0131k t\u00fcrlerine ve eri\u015fim desenlerine odaklan\u0131r. Veri de\u011fi\u015fiklikleri DynamoDB Streams ile yakalanabilir ve di\u011fer servislere veya Lambda fonksiyonlar\u0131na (\u00f6rne\u011fin, <code>OVERDUE<\/code> g\u00f6revleri g\u00fcncellemek i\u00e7in) g\u00f6nderilebilir, b\u00f6ylece denormalize edilmi\u015f verilerin tutarl\u0131l\u0131\u011f\u0131 sa\u011flan\u0131r.<\/p>\n<p>Bu vaka analizi, tek tablo tasar\u0131m\u0131n\u0131n ve \u00e7e\u015fitli GSI stratejilerinin, karma\u015f\u0131k ve \u00e7ok kirac\u0131l\u0131 bir ortamda nas\u0131l bir araya getirilerek esnek, y\u00fcksek performansl\u0131 ve maliyet etkin bir \u00e7\u00f6z\u00fcm sunabilece\u011fini g\u00f6stermektedir. Anahtar, her bir eri\u015fim desenini titizlikle analiz etmek ve DynamoDB'nin benzersiz \u00f6zelliklerini bu desenleri en iyi \u015fekilde kar\u015f\u0131lamak i\u00e7in kullanmakt\u0131r. Bu ileri d\u00fczey tekniklerin do\u011fru kombinasyonu, uygulaman\u0131z\u0131n gelecekteki b\u00fcy\u00fcme ve de\u011fi\u015fim ihtiya\u00e7lar\u0131na uyum sa\u011flamas\u0131na olanak tan\u0131r.<\/p>\n<h2>DynamoDB ile \u0130leri D\u00fczey Veri Modelleme Yolculu\u011funun \u00d6zeti<\/h2>\n<p>Bu makale boyunca, Amazon DynamoDB'nin temel mekanizmalar\u0131ndan ba\u015flayarak, ileri d\u00fczey veri modelleme tekniklerine kadar uzanan kapsaml\u0131 bir yolculuk yapt\u0131k. Modern, \u00f6l\u00e7eklenebilir ve y\u00fcksek performansl\u0131 uygulamalar geli\u015ftirmek i\u00e7in DynamoDB'nin neden kritik bir ara\u00e7 oldu\u011funu ve geleneksel ili\u015fkisel veritaban\u0131 yakla\u015f\u0131mlar\u0131ndan neden farkl\u0131 d\u00fc\u015f\u00fcnmemiz gerekti\u011fini anlamaya \u00e7al\u0131\u015ft\u0131k. \u00d6zellikle tek tablo tasar\u0131m\u0131n\u0131n sa\u011flad\u0131\u011f\u0131 maliyet, performans ve operasyonel kolayl\u0131k avantajlar\u0131n\u0131 detayl\u0131ca inceledik. Karma\u015f\u0131k eri\u015fim desenlerini y\u00f6netmek i\u00e7in Global Secondary Index'lerin (GSI'lar) g\u00fcc\u00fcn\u00fc ve bunlar\u0131n nas\u0131l seyrek dizinler (sparse indexes) olarak kullan\u0131labilece\u011fini g\u00f6rd\u00fck. Ayr\u0131ca, y\u00fcksek okuma performans\u0131n\u0131 sa\u011flamak i\u00e7in denormalizasyonun \u00f6nemini ve bunun getirebilece\u011fi avantajlar\u0131 tart\u0131\u015ft\u0131k.<\/p>\n<p>Unutulmamal\u0131d\u0131r ki, DynamoDB'de ba\u015far\u0131l\u0131 bir veri modellemesi, veritaban\u0131n\u0131n yeteneklerinden \u00e7ok, uygulaman\u0131z\u0131n veri eri\u015fim desenlerini derinlemesine anlamakla ba\u015flar. Her zaman, \"Uygulamam bu veriye nas\u0131l eri\u015fecek?\" sorusunu sormal\u0131s\u0131n\u0131z. Bu, Partition Key ve Sort Key se\u00e7imlerinizden, GSI'lar\u0131n\u0131z\u0131 nas\u0131l tasarlayaca\u011f\u0131n\u0131za kadar t\u00fcm modelleme kararlar\u0131n\u0131z\u0131 do\u011frudan etkileyecektir. Esnek \u015fema yap\u0131s\u0131, geli\u015ftiricilere b\u00fcy\u00fck bir \u00f6zg\u00fcrl\u00fck sunsa da, bu \u00f6zg\u00fcrl\u00fc\u011f\u00fcn ak\u0131ll\u0131ca kullan\u0131lmas\u0131, performans darbo\u011fazlar\u0131n\u0131 \u00f6nlemek ve maliyetleri optimize etmek i\u00e7in kilit rol oynar. Re:Invent 2025'teki DAT414 oturumu gibi etkinlikler, bu derinlemesine bilgiyi edinmek ve sekt\u00f6rdeki en iyi uygulamalar\u0131 \u00f6\u011frenmek i\u00e7in harika f\u0131rsatlar sunmaktad\u0131r. DynamoDB ile ileri d\u00fczey modelleme, bir sanat ve bilim kombinasyonudur; sab\u0131r, pratik ve s\u00fcrekli \u00f6\u011frenme gerektirir, ancak sonu\u00e7lar\u0131 uygulaman\u0131z\u0131n ba\u015far\u0131s\u0131 i\u00e7in paha bi\u00e7ilmez olabilir.<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular<\/h3>\n<p><strong>1. DynamoDB ne zaman kullan\u0131lmamal\u0131d\u0131r?<\/strong><br \/>\nDynamoDB, karma\u015f\u0131k SQL join'lerine veya OLAP (Online Analytical Processing) tarz\u0131 raporlama ihtiya\u00e7lar\u0131na yo\u011fun bir \u015fekilde ba\u011f\u0131ml\u0131 uygulamalar i\u00e7in ideal olmayabilir. Ayr\u0131ca, ili\u015fkisel veritabanlar\u0131n\u0131n g\u00fc\u00e7l\u00fc tutarl\u0131l\u0131k garantileri, karma\u015f\u0131k i\u015flem y\u00f6netimi veya veri b\u00fct\u00fcnl\u00fc\u011f\u00fc k\u0131s\u0131tlamalar\u0131 (Foreign Keys) sizin i\u00e7in kritikse, DynamoDB ilk tercihiniz olmayabilir. Esas olarak, uygulaman\u0131z\u0131n veri eri\u015fim desenleri \u00f6nceden tahmin edilemiyorsa veya \u00e7ok dinamikse, DynamoDB'nin anahtar-de\u011fer yap\u0131s\u0131 zorluk \u00e7\u0131karabilir.<\/p>\n<p><strong>2. Tek tablo tasar\u0131m\u0131n\u0131n dezavantajlar\u0131 var m\u0131d\u0131r?<\/strong><br \/>\nEvet, tek tablo tasar\u0131m\u0131n\u0131n baz\u0131 dezavantajlar\u0131 olabilir. \u0130lk \u00f6\u011frenme e\u011frisi y\u00fcksek olabilir \u00e7\u00fcnk\u00fc ili\u015fkisel veritaban\u0131 modellemesinden farkl\u0131 bir d\u00fc\u015f\u00fcnce yap\u0131s\u0131 gerektirir. Model karma\u015f\u0131kla\u015ft\u0131k\u00e7a, hangi varl\u0131\u011f\u0131n hangi anahtar kombinasyonuna sahip oldu\u011funu takip etmek zorla\u015fabilir. Ayr\u0131ca, belirli bir varl\u0131k t\u00fcr\u00fcn\u00fcn g\u00fcncellenmesi, ayn\u0131 Partition Key alt\u0131ndaki di\u011fer varl\u0131klar\u0131 etkileme riski ta\u015f\u0131r ve veri de\u011fi\u015fiklikleri genellikle DynamoDB Streams ve Lambda fonksiyonlar\u0131 gibi ek hizmetlerle y\u00f6netilmelidir.<\/p>\n<p><strong>3. Kapasite planlamas\u0131 nas\u0131l yap\u0131lmal\u0131?<\/strong><br \/>\nDynamoDB'de iki ana kapasite modu bulunur: Sa\u011flanan (Provisioned) ve \u0130ste\u011fe Ba\u011fl\u0131 (On-Demand).<br \/>\n*   <strong>\u0130ste\u011fe Ba\u011fl\u0131 (On-Demand):<\/strong> Beklenmedik veya de\u011fi\u015fken trafik y\u00fckleri olan uygulamalar i\u00e7in idealdir. Yaln\u0131zca kulland\u0131\u011f\u0131n\u0131z kadar \u00f6deme yapars\u0131n\u0131z ve manuel kapasite planlamas\u0131 gerektirmez. Ancak, \u00e7ok tahmin edilebilir ve y\u00fcksek hacimli i\u015f y\u00fcklerinde sa\u011flanan kapasite modundan daha pahal\u0131 olabilir.<br \/>\n*   <strong>Sa\u011flanan (Provisioned):<\/strong> Tahmin edilebilir trafik y\u00fckleri olan uygulamalar i\u00e7in uygundur. Belirli bir okuma ve yazma kapasitesi (RCU\/WCU) ay\u0131r\u0131rs\u0131n\u0131z ve maliyet etkinli\u011fi daha y\u00fcksek olabilir. Otomatik \u00f6l\u00e7eklendirme ile yo\u011fun d\u00f6nemlerde kapasitenizi otomatik olarak art\u0131r\u0131p azaltabilirsiniz. Kapasite planlamas\u0131, ge\u00e7mi\u015f trafik verilerini analiz etmeyi ve gelecekteki b\u00fcy\u00fcmeyi tahmin etmeyi i\u00e7erir.<\/p>\n<p><strong>4. LSI ve GSI aras\u0131ndaki temel fark nedir?<\/strong><br \/>\nTemel fark, Partition Key'leridir. LSI (Local Secondary Index), ana tablonun Partition Key'iyle ayn\u0131 Partition Key'e sahip olmal\u0131d\u0131r, ancak farkl\u0131 bir Sort Key'e sahip olabilir. GSI (Global Secondary Index) ise, ana tablonun Partition Key'inden farkl\u0131 bir Partition Key'e sahip olabilir. Bu, GSI'lar\u0131n ana tablodan tamamen farkl\u0131 bir sorgulama boyutuna izin vermesini sa\u011flar ve kendi okuma\/yazma kapasitesine sahip olabilirler. LSI'lar ana tablo kapasitesini kullan\u0131r ve g\u00fc\u00e7l\u00fc tutarl\u0131l\u0131k sa\u011flarken, GSI'lar nihai tutarl\u0131l\u0131k sa\u011flar.<\/p>\n<p><strong>5. Veri modellemede yap\u0131lan en yayg\u0131n hata nedir?<\/strong><br \/>\nDynamoDB veri modellemesinde yap\u0131lan en yayg\u0131n hata, ili\u015fkisel veritaban\u0131 zihniyetiyle modellemeye \u00e7al\u0131\u015fmakt\u0131r. Bu, ayr\u0131 varl\u0131klar i\u00e7in ayr\u0131 tablolar olu\u015fturmak, anahtar se\u00e7imini g\u00f6z ard\u0131 etmek ve eri\u015fim desenlerini \u00f6nceden tan\u0131mlamadan \u015fema olu\u015fturmak anlam\u0131na gelir. Sonu\u00e7 olarak, bu yakla\u015f\u0131m gereksiz JOIN i\u015flemleri, verimsiz sorgular, \"hot partition\" sorunlar\u0131 ve y\u00fcksek maliyetlere yol a\u00e7ar. Do\u011fru yakla\u015f\u0131m, her zaman uygulaman\u0131z\u0131n veriye nas\u0131l eri\u015fece\u011fini planlamak ve DynamoDB'nin tek tablo tasar\u0131m\u0131 ve GSI'lar gibi \u00f6zelliklerini bu desenleri kar\u015f\u0131lamak i\u00e7in kullanmakt\u0131r.<br \/>\n<\/article>\n","protected":false},"excerpt":{"rendered":"Amazon DynamoDB ile \u0130leri D\u00fczey Veri Modelleme Teknikleri Modern bulut uygulamalar\u0131n\u0131n vazge\u00e7ilmez bir bile\u015feni olan veritabanlar\u0131, s\u00fcrekli artan&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-35954","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Amazon DynamoDB ile Veri Modellemenin G\u00fcc\u00fc Nereden Geliyor?<\/title>\n<meta name=\"description\" content=\"Hi\u00e7bir etiketi bulunamad\u0131.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Amazon DynamoDB ile Veri Modellemenin G\u00fcc\u00fc Nereden Geliyor?\" \/>\n<meta property=\"og:description\" content=\"Hi\u00e7bir etiketi bulunamad\u0131.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-12-06T00:31:17+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"32 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Amazon DynamoDB ile Veri Modellemenin G\u00fcc\u00fc Nereden Geliyor?\",\"datePublished\":\"2025-12-06T00:31:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/\"},\"wordCount\":5565,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/\",\"name\":\"Amazon DynamoDB ile Veri Modellemenin G\u00fcc\u00fc Nereden Geliyor?\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-12-06T00:31:17+00:00\",\"description\":\"Hi\u00e7bir etiketi bulunamad\u0131.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Amazon DynamoDB ile Veri Modellemenin G\u00fcc\u00fc Nereden Geliyor?\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Amazon DynamoDB ile Veri Modellemenin G\u00fcc\u00fc Nereden Geliyor?","description":"Hi\u00e7bir etiketi bulunamad\u0131.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/","og_locale":"tr_TR","og_type":"article","og_title":"Amazon DynamoDB ile Veri Modellemenin G\u00fcc\u00fc Nereden Geliyor?","og_description":"Hi\u00e7bir etiketi bulunamad\u0131.","og_url":"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-12-06T00:31:17+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"32 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Amazon DynamoDB ile Veri Modellemenin G\u00fcc\u00fc Nereden Geliyor?","datePublished":"2025-12-06T00:31:17+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/"},"wordCount":5565,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/","url":"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/","name":"Amazon DynamoDB ile Veri Modellemenin G\u00fcc\u00fc Nereden Geliyor?","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-12-06T00:31:17+00:00","description":"Hi\u00e7bir etiketi bulunamad\u0131.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/amazon-dynamodb-ile-veri-modellemenin-gucu-nereden-geliyor\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Amazon DynamoDB ile Veri Modellemenin G\u00fcc\u00fc Nereden Geliyor?"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/35954","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=35954"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/35954\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=35954"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=35954"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=35954"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}