<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Data-Ownership on IT Comparison</title><link>https://comparison.metacog.co.kr/tags/data-ownership/</link><description>Recent content in Data-Ownership on IT Comparison</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Tue, 04 Aug 2026 05:14:24 +0900</lastBuildDate><atom:link href="https://comparison.metacog.co.kr/tags/data-ownership/index.xml" rel="self" type="application/rss+xml"/><item><title>Shared Database vs Database per Service: Data Ownership in Microservices</title><link>https://comparison.metacog.co.kr/posts/2026-08-04-shared-database-vs-database-per-service-data-ownership-in-mi/</link><pubDate>Tue, 04 Aug 2026 05:14:24 +0900</pubDate><guid>https://comparison.metacog.co.kr/posts/2026-08-04-shared-database-vs-database-per-service-data-ownership-in-mi/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;A &lt;strong class="kw"&gt;shared database&lt;/strong&gt; lets multiple services read and write the same tables through one common schema, while &lt;strong class="kw"&gt;database per service&lt;/strong&gt; gives each service its own private data store that only it can touch directly. The choice determines how tightly services are coupled at the data layer, how independently teams can deploy, and how much work cross-service queries and transactions require.&lt;/p&gt;
&lt;h2 id="comparison-diagram"&gt;Comparison Diagram&lt;/h2&gt;
&lt;div class="compare-diagram"&gt;
&lt;svg viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg"&gt;&lt;line x1="320" y1="20" x2="320" y2="340" style="stroke:var(--border)" stroke-width="1" stroke-dasharray="4 4"/&gt;&lt;text x="160" y="32" text-anchor="middle" style="fill:var(--primary)" font-size="16" font-weight="bold"&gt;Shared Database&lt;/text&gt;&lt;text x="480" y="32" text-anchor="middle" style="fill:var(--primary)" font-size="16" font-weight="bold"&gt;Database per Service&lt;/text&gt;&lt;rect x="30" y="55" width="70" height="35" rx="4" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;text x="65" y="77" text-anchor="middle" style="fill:var(--content)" font-size="11"&gt;Service A&lt;/text&gt;&lt;rect x="125" y="55" width="70" height="35" rx="4" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;text x="160" y="77" text-anchor="middle" style="fill:var(--content)" font-size="11"&gt;Service B&lt;/text&gt;&lt;rect x="220" y="55" width="70" height="35" rx="4" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;text x="255" y="77" text-anchor="middle" style="fill:var(--content)" font-size="11"&gt;Service C&lt;/text&gt;&lt;line x1="65" y1="90" x2="140" y2="168" style="stroke:var(--secondary)" stroke-width="1.5"/&gt;&lt;line x1="160" y1="90" x2="160" y2="168" style="stroke:var(--secondary)" stroke-width="1.5"/&gt;&lt;line x1="255" y1="90" x2="180" y2="168" style="stroke:var(--secondary)" stroke-width="1.5"/&gt;&lt;rect x="115" y="170" width="90" height="55" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;ellipse cx="160" cy="170" rx="45" ry="12" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;ellipse cx="160" cy="225" rx="45" ry="12" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;text x="160" y="204" text-anchor="middle" style="fill:var(--content)" font-size="12" font-weight="bold"&gt;Shared DB&lt;/text&gt;&lt;text x="160" y="300" text-anchor="middle" style="fill:var(--secondary)" font-size="11"&gt;one schema, every service reads/writes it directly&lt;/text&gt;&lt;rect x="355" y="48" width="100" height="180" rx="6" style="fill:none;stroke:var(--border)" stroke-width="1" stroke-dasharray="4 3"/&gt;&lt;rect x="450" y="48" width="100" height="180" rx="6" style="fill:none;stroke:var(--border)" stroke-width="1" stroke-dasharray="4 3"/&gt;&lt;rect x="545" y="48" width="90" height="180" rx="6" style="fill:none;stroke:var(--border)" stroke-width="1" stroke-dasharray="4 3"/&gt;&lt;rect x="370" y="55" width="70" height="35" rx="4" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;text x="405" y="77" text-anchor="middle" style="fill:var(--content)" font-size="11"&gt;Service X&lt;/text&gt;&lt;rect x="465" y="55" width="70" height="35" rx="4" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;text x="500" y="77" text-anchor="middle" style="fill:var(--content)" font-size="11"&gt;Service Y&lt;/text&gt;&lt;rect x="560" y="55" width="70" height="35" rx="4" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;text x="595" y="77" text-anchor="middle" style="fill:var(--content)" font-size="11"&gt;Service Z&lt;/text&gt;&lt;line x1="405" y1="90" x2="405" y2="150" style="stroke:var(--secondary)" stroke-width="1.5"/&gt;&lt;line x1="500" y1="90" x2="500" y2="150" style="stroke:var(--secondary)" stroke-width="1.5"/&gt;&lt;line x1="595" y1="90" x2="595" y2="150" style="stroke:var(--secondary)" stroke-width="1.5"/&gt;&lt;rect x="375" y="150" width="60" height="42" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;ellipse cx="405" cy="150" rx="30" ry="8" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;ellipse cx="405" cy="192" rx="30" ry="8" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;text x="405" y="175" text-anchor="middle" style="fill:var(--content)" font-size="10"&gt;DB X&lt;/text&gt;&lt;rect x="470" y="150" width="60" height="42" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;ellipse cx="500" cy="150" rx="30" ry="8" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;ellipse cx="500" cy="192" rx="30" ry="8" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;text x="500" y="175" text-anchor="middle" style="fill:var(--content)" font-size="10"&gt;DB Y&lt;/text&gt;&lt;rect x="565" y="150" width="60" height="42" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;ellipse cx="595" cy="150" rx="30" ry="8" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;ellipse cx="595" cy="192" rx="30" ry="8" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;text x="595" y="175" text-anchor="middle" style="fill:var(--content)" font-size="10"&gt;DB Z&lt;/text&gt;&lt;text x="480" y="300" text-anchor="middle" style="fill:var(--secondary)" font-size="11"&gt;each service owns a private schema, accessed only via its API&lt;/text&gt;&lt;/svg&gt;
&lt;/div&gt;
&lt;h2 id="comparison-table"&gt;Comparison Table&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Shared Database&lt;/th&gt;
&lt;th&gt;Database per Service&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Data ownership&lt;/td&gt;
&lt;td&gt;No single owner — all services see and can modify the same tables&lt;/td&gt;
&lt;td&gt;Each service exclusively owns its schema; no one else can touch it directly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access path&lt;/td&gt;
&lt;td&gt;Services query the database directly, often with raw SQL against shared tables&lt;/td&gt;
&lt;td&gt;Other services only get data through the owning service&amp;rsquo;s API or published events&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-service transactions&lt;/td&gt;
&lt;td&gt;Native ACID transactions and joins span all the data in one commit&lt;/td&gt;
&lt;td&gt;No shared transaction; consistency across services needs sagas or eventual consistency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cross-service queries&lt;/td&gt;
&lt;td&gt;Simple SQL joins pull data from any table in one query&lt;/td&gt;
&lt;td&gt;Requires API composition, data replication, or a separate CQRS read model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Schema changes&lt;/td&gt;
&lt;td&gt;A column or table change can silently break unrelated services&lt;/td&gt;
&lt;td&gt;Schema changes are internal; only the public API contract must stay stable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Technology choice&lt;/td&gt;
&lt;td&gt;All services are locked into one database engine and schema&lt;/td&gt;
&lt;td&gt;Each service can pick the storage engine that fits its data (polyglot persistence)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Failure isolation&lt;/td&gt;
&lt;td&gt;A database outage or lock contention affects every service at once&lt;/td&gt;
&lt;td&gt;An outage in one service&amp;rsquo;s database doesn&amp;rsquo;t directly take down the others&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Operational overhead&lt;/td&gt;
&lt;td&gt;One database to provision, back up, and tune&lt;/td&gt;
&lt;td&gt;N databases to provision, monitor, back up, and scale independently&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="key-differences"&gt;Key Differences&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Shared database gives every service direct access to the same tables, so a change in one place can silently break another service&amp;rsquo;s queries — a form of &lt;strong class="kw"&gt;tight coupling&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Database per service forces all cross-service data access through an API, giving each service true &lt;strong class="kw"&gt;encapsulation&lt;/strong&gt; of its data.&lt;/li&gt;
&lt;li&gt;Cross-entity consistency is a native &lt;strong class="kw"&gt;ACID transaction&lt;/strong&gt; in a shared database, but needs a &lt;strong class="kw"&gt;saga pattern&lt;/strong&gt; or eventual consistency once data is split per service.&lt;/li&gt;
&lt;li&gt;Reporting and ad-hoc joins are trivial with a shared database&amp;rsquo;s SQL, while database per service usually needs a separate &lt;strong class="kw"&gt;CQRS read model&lt;/strong&gt; to answer cross-service queries.&lt;/li&gt;
&lt;li&gt;Database per service allows &lt;strong class="kw"&gt;polyglot persistence&lt;/strong&gt; — each service picks its own database engine — whereas shared database locks every service to one engine and schema.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="when-to-use-each"&gt;When to Use Each&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Shared Database&lt;/strong&gt;&lt;/p&gt;</description></item></channel></rss>