{"id":1329,"date":"2026-03-24T09:00:32","date_gmt":"2026-03-24T16:00:32","guid":{"rendered":"https:\/\/www.kenwalger.com\/blog\/?p=1329"},"modified":"2026-05-05T07:11:27","modified_gmt":"2026-05-05T14:11:27","slug":"designing-a-schema-for-physical-objects","status":"publish","type":"post","link":"https:\/\/www.kenwalger.com\/blog\/data-engineering\/designing-a-schema-for-physical-objects\/","title":{"rendered":"The Backyard Quarry, Part 2: Designing a Schema for Physical Objects"},"content":{"rendered":"<p>In the <a href=\"https:\/\/www.kenwalger\/blog\/software-engineering\/the-backyard-quarry-turning-rocks-into-data\">first post of this series<\/a> we set the stage for the <strong>Backyard Quarry<\/strong> project.<\/p>\n<p>Once you decide every rock in the yard should have a record, the next question appears immediately:<\/p>\n<p>What exactly should we record?<\/p>\n<p>It\u2019s a deceptively simple question. And like most simple questions in engineering, it opens the door to a surprisingly large number of decisions.<\/p>\n<h2>The First Attempt<\/h2>\n<p>The most straightforward approach is to keep things minimal.<\/p>\n<p>Each rock gets an identifier and a few attributes.<\/p>\n<p>Something like:<\/p>\n<pre><code class=\"language-plaintext\">rock_id\nsize\nprice\n<\/code><\/pre>\n<p>At first glance, this seems reasonable.<\/p>\n<p>We can identify the rock. We can describe it in some vague way. We can assign a price.<\/p>\n<p>But this model breaks down almost immediately.<\/p>\n<p>\u201cSize\u201d is ambiguous. Is that weight? Volume? Longest dimension? All of the above?<\/p>\n<p>Two rocks of the same \u201csize\u201d might behave very differently when you try to move them.<\/p>\n<p>And more importantly, this model doesn\u2019t capture anything about the rock beyond its most basic characteristics.<\/p>\n<p>It\u2019s enough to sell a rock.<\/p>\n<p>It\u2019s not enough to understand one.<\/p>\n<h2>Expanding the Model<\/h2>\n<p>To make the system more useful, we need to be more explicit.<\/p>\n<p>A slightly richer model might look like this:<\/p>\n<pre><code class=\"language-plaintext\">rock_id\nweight_lb\nlength_cm\nwidth_cm\nheight_cm\ncolor\nrock_type\nlocation_found\nstatus\n<\/code><\/pre>\n<p>Now we\u2019re getting somewhere.<\/p>\n<p>We can distinguish between rocks that look similar but behave differently.<\/p>\n<p>We can track where each rock came from.<\/p>\n<p>We can start to answer questions like:<\/p>\n<ul>\n<li>How many rocks do we have in a given area?<\/li>\n<li>What size distribution does the dataset have?<\/li>\n<li>Which rocks are suitable for different uses?<\/li>\n<\/ul>\n<p>This is the point where the rock pile starts to feel less like a random collection and more like a dataset.<\/p>\n<h2>The Object Data Model<\/h2>\n<p>At a higher level, what we\u2019re really doing is separating a physical object into a few distinct components.<\/p>\n<figure id=\"attachment_1330\" aria-describedby=\"caption-attachment-1330\" style=\"width: 840px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" data-attachment-id=\"1330\" data-permalink=\"https:\/\/www.kenwalger.com\/blog\/data-engineering\/designing-a-schema-for-physical-objects\/attachment\/rock-digital-object-model-diagram\/\" data-orig-file=\"https:\/\/www.kenwalger.com\/blog\/wp-content\/uploads\/2026\/03\/rock-digital-object-model-diagram-scaled.png\" data-orig-size=\"2560,634\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"rock-digital-object-model-diagram\" data-image-description=\"\" data-image-caption=\"&lt;p&gt;A simple model for representing a physical object as structured data and associated assets.&lt;\/p&gt;\n\" data-large-file=\"https:\/\/www.kenwalger.com\/blog\/wp-content\/uploads\/2026\/03\/rock-digital-object-model-diagram-1024x254.png\" class=\"size-large wp-image-1330\" src=\"https:\/\/www.kenwalger.com\/blog\/wp-content\/uploads\/2026\/03\/rock-digital-object-model-diagram-1024x254.png\" alt=\"Diagram showing how a physical rock is represented as a digital record with metadata, images, and a 3D model.\" width=\"840\" height=\"208\" srcset=\"https:\/\/www.kenwalger.com\/blog\/wp-content\/uploads\/2026\/03\/rock-digital-object-model-diagram-1024x254.png 1024w, https:\/\/www.kenwalger.com\/blog\/wp-content\/uploads\/2026\/03\/rock-digital-object-model-diagram-300x74.png 300w, https:\/\/www.kenwalger.com\/blog\/wp-content\/uploads\/2026\/03\/rock-digital-object-model-diagram-768x190.png 768w, https:\/\/www.kenwalger.com\/blog\/wp-content\/uploads\/2026\/03\/rock-digital-object-model-diagram-1536x380.png 1536w, https:\/\/www.kenwalger.com\/blog\/wp-content\/uploads\/2026\/03\/rock-digital-object-model-diagram-2048x507.png 2048w, https:\/\/www.kenwalger.com\/blog\/wp-content\/uploads\/2026\/03\/rock-digital-object-model-diagram-1200x297.png 1200w\" sizes=\"auto, (max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\" \/><figcaption id=\"caption-attachment-1330\" class=\"wp-caption-text\">A simple model for representing a physical object as structured data and associated assets.<\/figcaption><\/figure>\n<p>Each rock has:<\/p>\n<ul>\n<li><strong>metadata<\/strong> describing its properties<\/li>\n<li><strong>images<\/strong> representing its appearance<\/li>\n<li>optionally, a <strong>3D model<\/strong> capturing its shape<\/li>\n<\/ul>\n<p>This separation turns out to be important.<\/p>\n<p>Metadata is small, structured, and easy to query.<\/p>\n<p>Images and 3D models are large, unstructured assets that need to be stored and referenced.<\/p>\n<p>Keeping those concerns separate is a pattern that shows up in many real-world systems.<\/p>\n<h2>The Identity Problem<\/h2>\n<p>Once the schema starts to take shape, another question appears.<\/p>\n<p>How do we uniquely identify a rock?<\/p>\n<p>There are a few options:<\/p>\n<ul>\n<li>sequential IDs (<code>rock_001<\/code>, <code>rock_002<\/code>)<\/li>\n<li>UUIDs<\/li>\n<li>physical tags attached to rocks<\/li>\n<li>some form of image-based identification<\/li>\n<\/ul>\n<p>For a small backyard dataset, almost anything works.<\/p>\n<p>But the choice matters more as the system grows.<\/p>\n<p>Sequential IDs are easy to read but require coordination.<\/p>\n<p>UUIDs are globally unique but harder to work with manually.<\/p>\n<p>Physical tags introduce a connection between the digital record and the real-world object.<\/p>\n<p>Even in a simple system, identity becomes a design decision.<\/p>\n<h2>Classification: The Quarry Taxonomy<\/h2>\n<p>At some point, it becomes useful to introduce categories.<\/p>\n<p>Originally this was just a convenience.<\/p>\n<p>But like many things in this project, it quickly became something more formal.<\/p>\n<p>A simple classification system might look like this:<\/p>\n<pre><code class=\"language-plaintext\">Class 0 \u2014 Pebble\nClass 1 \u2014 Hand Sample\nClass 2 \u2014 Landscaping Rock\nClass 3 \u2014 Wheelbarrow Class\nClass 4 \u2014 Engine Block Class\nClass 5 \u2014 Heavy Machinery Class\n<\/code><\/pre>\n<p>Each class roughly corresponds to how the rock is handled.<\/p>\n<p>This turns out to be surprisingly useful.<\/p>\n<p>Instead of asking for exact dimensions, we can filter by class:<\/p>\n<ul>\n<li>\u201cShow me all Pebble Class rocks\u201d<\/li>\n<li>\u201cExclude anything above Wheelbarrow Class\u201d<\/li>\n<\/ul>\n<p>In other words, we\u2019ve introduced a <strong>derived attribute<\/strong> \u2014 something computed from the underlying data rather than stored arbitrarily.<\/p>\n<p>This is exactly how classification systems evolve in real datasets.<\/p>\n<h2>Thinking About Lifecycle<\/h2>\n<p>Rocks don\u2019t change much physically, but their role in the system does.<\/p>\n<p>A rock might move through states like:<\/p>\n<pre><code class=\"language-plaintext\">collected\ncataloged\nlisted_for_sale\nsold\n<\/code><\/pre>\n<p>Tracking this lifecycle introduces another dimension to the data.<\/p>\n<p>Now we\u2019re not just modeling objects.<\/p>\n<p>We\u2019re modeling *objects over *.<\/p>\n<p>Even in a simple system, state and transitions begin to matter.<\/p>\n<h2>The Tradeoffs<\/h2>\n<p>At this point, the schema is already doing useful work.<\/p>\n<p>But it\u2019s also clear that there\u2019s no perfect design.<\/p>\n<p>Every decision involves tradeoffs:<\/p>\n<ul>\n<li>more fields vs simplicity<\/li>\n<li>normalized structure vs ease of use<\/li>\n<li>flexibility vs consistency<\/li>\n<\/ul>\n<p>The goal isn\u2019t to design the perfect schema on the first try.<\/p>\n<p>The goal is to design something that can evolve.<\/p>\n<p>Because as soon as we start capturing real data, we\u2019ll learn what we got wrong.<\/p>\n<h2>What Comes Next<\/h2>\n<p>With a basic schema in place, the next challenge becomes obvious.<\/p>\n<p>We know what we want to store.<\/p>\n<p>Now we need to figure out how to capture it.<\/p>\n<p>In the next post, we\u2019ll look at how to turn a physical rock into images, measurements, and potentially a 3D model \u2014 and how that process introduces its own set of constraints.<\/p>\n<p>Because it turns out that collecting data from the physical world is rarely as clean as designing a schema on paper.<\/p>\n<h3>The Rock Quarry Series<\/h3>\n<ul>\n<li><a href=\"https:\/\/www.kenwalger.com\/blog\/software-engineering\/the-backyard-quarry-turning-rocks-into-data\">Turning Rocks into Data<\/a><\/li>\n<li><a href=\"https:\/\/www.kenwalger.com\/blog\/data-engineering\/designing-a-schema-for-physical-objects\">Designing a Schema for Physical Objects<\/a> &#8211; <em>This Post<\/em><\/li>\n<li><a href=\"https:\/\/www.kenwalger.com\/blog\/data-engineering\/capturing-physical-objects-data-pipeline\">Capturing the Physical World<\/a><\/li>\n<li><a href=\"https:\/\/www.kenwalger.com\/blog\/data-engineering\/searching-physical-objects-data-indexing\">Searching a Pile of Rocks<\/a><\/li>\n<li><a href=\"https:\/\/www.kenwalger.com\/blog\/data-engineering\/digital-twins-physical-objects-explained\">Digital Twins for Physical Objects<\/a><\/li>\n<li><a href=\"https:\/\/www.kenwalger.com\/blog\/data-engineering\/scaling-data-pipelines-physical-objects\">Scaling the Quarry<\/a><\/li>\n<li><a href=\"https:\/\/www.kenwalger.com\/blog\/data-engineering\/system-design-patterns-real-world-data-platforms\">Systems Beyond the Backyard<\/a><\/li>\n<li><a href=\"https:\/\/www.kenwalger.com\/blog\/data-engineering\/from-rocks-to-reality-system-design-patterns\">From Rocks to Reality<\/a><\/li>\n<\/ul>\n<a class=\"synved-social-button synved-social-button-share synved-social-size-48 synved-social-resolution-single synved-social-provider-facebook nolightbox\" data-provider=\"facebook\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Facebook\" href=\"https:\/\/www.facebook.com\/sharer.php?u=https%3A%2F%2Fwww.kenwalger.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1329&#038;t=The%20Backyard%20Quarry%2C%20Part%202%3A%20Designing%20a%20Schema%20for%20Physical%20Objects&#038;s=100&#038;p&#091;url&#093;=https%3A%2F%2Fwww.kenwalger.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1329&#038;p&#091;images&#093;&#091;0&#093;=https%3A%2F%2Fwww.kenwalger.com%2Fblog%2Fwp-content%2Fuploads%2F2026%2F04%2Fblog-of-ken-w.-alger-69ea5ab61f4e0.png&#038;p&#091;title&#093;=The%20Backyard%20Quarry%2C%20Part%202%3A%20Designing%20a%20Schema%20for%20Physical%20Objects\" style=\"font-size: 0px;width:48px;height:48px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"Facebook\" title=\"Share on Facebook\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"48\" height=\"48\" style=\"display: inline;width:48px;height:48px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/www.kenwalger.com\/blog\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/96x96\/facebook.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-48 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fwww.kenwalger.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1329&#038;text=Hey%20check%20this%20out\" style=\"font-size: 0px;width:48px;height:48px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"48\" height=\"48\" style=\"display: inline;width:48px;height:48px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/www.kenwalger.com\/blog\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/96x96\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-48 synved-social-resolution-single synved-social-provider-reddit nolightbox\" data-provider=\"reddit\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Reddit\" href=\"https:\/\/www.reddit.com\/submit?url=https%3A%2F%2Fwww.kenwalger.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1329&#038;title=The%20Backyard%20Quarry%2C%20Part%202%3A%20Designing%20a%20Schema%20for%20Physical%20Objects\" style=\"font-size: 0px;width:48px;height:48px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"reddit\" title=\"Share on Reddit\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"48\" height=\"48\" style=\"display: inline;width:48px;height:48px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/www.kenwalger.com\/blog\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/96x96\/reddit.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-48 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fwww.kenwalger.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1329&#038;title=The%20Backyard%20Quarry%2C%20Part%202%3A%20Designing%20a%20Schema%20for%20Physical%20Objects\" style=\"font-size: 0px;width:48px;height:48px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"48\" height=\"48\" style=\"display: inline;width:48px;height:48px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/www.kenwalger.com\/blog\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/96x96\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-48 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=The%20Backyard%20Quarry%2C%20Part%202%3A%20Designing%20a%20Schema%20for%20Physical%20Objects&#038;body=Hey%20check%20this%20out:%20https%3A%2F%2Fwww.kenwalger.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F1329\" style=\"font-size: 0px;width:48px;height:48px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"48\" height=\"48\" style=\"display: inline;width:48px;height:48px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/www.kenwalger.com\/blog\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/96x96\/mail.png\" \/><\/a>","protected":false},"excerpt":{"rendered":"<p>In the first post of this series we set the stage for the Backyard Quarry project. Once you decide every rock in the yard should have a record, the next question appears immediately: What exactly should we record? It\u2019s a deceptively simple question. And like most simple questions in engineering, it opens the door to &hellip; <a href=\"https:\/\/www.kenwalger.com\/blog\/data-engineering\/designing-a-schema-for-physical-objects\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;The Backyard Quarry, Part 2: Designing a Schema for Physical Objects&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":1527,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"pmpro_default_level":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[1739,1738],"tags":[1746,1740,1745,1741,1713],"yst_prominent_words":[99,784,756,290,695,576,782,797,757],"class_list":["post-1329","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-data-engineering","category-software-engineering","tag-backend-engineering","tag-data-modeling","tag-database-design","tag-digital-twins","tag-system-design","pmpro-has-access"],"jetpack_featured_media_url":"https:\/\/www.kenwalger.com\/blog\/wp-content\/uploads\/2026\/04\/blog-of-ken-w.-alger-69ea5ab61f4e0.png","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8lx70-lr","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/posts\/1329","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/comments?post=1329"}],"version-history":[{"count":8,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/posts\/1329\/revisions"}],"predecessor-version":[{"id":1571,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/posts\/1329\/revisions\/1571"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/media\/1527"}],"wp:attachment":[{"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/media?parent=1329"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/categories?post=1329"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/tags?post=1329"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/www.kenwalger.com\/blog\/wp-json\/wp\/v2\/yst_prominent_words?post=1329"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}