{"id":6901,"date":"2023-06-15T00:00:00","date_gmt":"2023-06-15T04:00:00","guid":{"rendered":"https:\/\/www.sisense.com\/better-sql-schema\/"},"modified":"2024-10-23T01:06:55","modified_gmt":"2024-10-23T05:06:55","slug":"better-sql-schema","status":"publish","type":"post","link":"https:\/\/www.sisense.com\/blog\/better-sql-schema\/","title":{"rendered":"10 rules for a better SQL schema"},"content":{"rendered":"\r\n<p>There are a lot of decisions to make when creating new tables and data warehouses. Some that seem inconsequential at the time end up causing you and your users pain for the life of the database.<\/p>\r\n\r\n\r\n\r\n<p>We\u2019ve worked with thousands of people and their databases and, after countless hours of reading and writing queries, we\u2019ve seen almost everything. Here are our top 10 rules for creating pain-free schemas.<\/p>\r\n\r\n\r\n\r\n<p><strong>SQL Analytics Starter Kit: Best Practices, Tips, and Tricks:<\/strong><\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">1. Only use lowercase letters, numbers, and underscores<\/h2>\r\n\r\n\r\n\r\n<p>Don\u2019t use dots, spaces, or dashes in database, schema, table, or column names. Dots are for identifying objects, usually in the database.schema.table.column pattern.<\/p>\r\n\r\n\r\n\r\n<p>Having dots in names of objects will cause confusion. Likewise, using spaces in object names will force you to add a bunch of otherwise unnecessary quotes to your query:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>select \"user name\" from events\r\n-- vs\r\nselect user_name from events<\/code><\/pre>\r\n\r\n\r\n\r\n<p>Queries are harder to write if you use capital letters in table or column names. If everything is lowercase, no one has to remember if the <strong>users <\/strong>table is <strong>Users <\/strong>or <strong>users<\/strong>.<\/p>\r\n\r\n\r\n\r\n<p>And when you eventually change databases or replicate your tables into a warehouse, you won\u2019t need to remember which database is case-sensitive, as only some are.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">2. Use simple, descriptive column names<\/h2>\r\n\r\n\r\n\r\n<p>If the users table needs a foreign key to the packages table, name the key package_id. Avoid short and cryptic names like pkg_fk; others won\u2019t know what that means. Descriptive names make it easier for others to understand the schema, which is vital to maintaining efficiency as the team grows.<\/p>\r\n\r\n\r\n\r\n<p>Don\u2019t use ambiguous names for <a href=\"https:\/\/en.wikipedia.org\/wiki\/Polymorphism_%28computer_science%29\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">polymorphic data<\/a>. If you find yourself creating columns with an item_type or item_value pattern, you\u2019re likely better off using more columns with specific names like photo_count, view_count, transaction_price.<\/p>\r\n\r\n\r\n\r\n<p>This way, the contents of a column are always known from the schema, and are not dependent on other values in the row.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>select sum(item_value) as photo_count\r\nfrom items\r\nwhere item_type = 'Photo Count'\r\n-- vs\r\nselect sum(photo_count) from items<\/code><\/pre>\r\n\r\n\r\n\r\n<p>Don\u2019t prefix column names with the name of the containing table. It\u2019s generally unhelpful to have the users table contain columns like user_birthday, user_created_at, user_name.<\/p>\r\n\r\n\r\n\r\n<p>Avoid using reserved keywords like column, tag, and user as column names. You\u2019ll have to use extra quotes in your queries and forgetting to do so will get you very confusing error messages. The database can wildly misunderstand the query if a keyword shows up where a column name should be.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">3. Use simple, descriptive table names<\/h2>\r\n\r\n\r\n\r\n<p>If the table name is made of up of multiple words, use underscores to separate the words. It\u2019s much easier to read package_deliveries than packagedeliveries.<\/p>\r\n\r\n\r\n\r\n<p>And whenever possible, use one word instead of two: deliveries is even easier to read.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>select * from packagedeliveries\r\n-- vs\r\nselect * from deliveries<\/code><\/pre>\r\n\r\n\r\n\r\n<p>Don\u2019t prefix tables to imply a schema. If you need the table grouped into a scope, put those tables into a schema. Having tables with names like store_items, store_transactions, store_coupons, like prefixed column names, is generally not worth the extra typing.<\/p>\r\n\r\n\r\n\r\n<p>We recommend using pluralized names for tables (e.g. packages), and pluralizing both words in the name of a join table (e.g. packages_users). Singular table names are more likely to accidentally collide with reserved keywords and are generally less readable in queries.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">4. Have an integer primary key<\/h2>\r\n\r\n\r\n\r\n<p>Even if you\u2019re using UUIDs or it doesn\u2019t make sense (e.g. for join tables), add the standard id column with an auto-incrementing integer sequence. This kind of key makes certain analyses much easier, like <a href=\"\/blog\/4-ways-to-join-only-the-first-row-in-sql\/\">selecting only the first row of a group<\/a>.<\/p>\r\n\r\n\r\n\r\n<p>And if an import job ever duplicates data, this key will be a life-saver because you\u2019ll be able to delete specific rows:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>delete from my_table\r\nwhere id in (select ...) as duplicated_ids<\/code><\/pre>\r\n\r\n\r\n\r\n<p>Avoid multi-column primary keys. They can be difficult to reason about when trying to write efficient queries, and very difficult to change. Use an integer primary key, a multi-column unique constraint, and several single-column indexes instead.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">5. Be consistent with foreign keys<\/h2>\r\n\r\n\r\n\r\n<p>There are many styles for naming primary and foreign keys. Our recommendation, and the most popular, is to have a primary key called id for any table foo, and have all foreign keys be named foo_id.<\/p>\r\n\r\n\r\n\r\n<p>Another popular style uses globally unique key names, where the foo table has a primary key called foo_id and all foreign keys are also called foo_id. This can get confusing or have name collisions if you use abbreviations (e.g. uid for the users table), so don\u2019t abbreviate.<\/p>\r\n\r\n\r\n\r\n<p>Whatever style you choose, stick to it. Don\u2019t use uid in some places and user_id or users_fk in others.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>select *\r\nfrom packages\r\n  join users on users.user_id = packages.uid\r\n-- vs\r\nselect *\r\nfrom packages\r\n  join users on users.id = packages.user_id\r\n-- or\r\nselect *\r\nfrom packages\r\n  join users using (user_id)<\/code><\/pre>\r\n\r\n\r\n\r\n<p>And be careful with foreign keys that don\u2019t obviously match up to a table. A column named owner_id might be a foreign key to the users table, or it might not. Name the column user_id or, if necessary, owner_user_id.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">6. Store datetimes as datetimes<\/h2>\r\n\r\n\r\n\r\n<p>Don\u2019t store Unix timestamps or strings as dates: convert them to datetimes instead. While SQL\u2019s date math functions aren\u2019t the greatest, doing it yourself on timestamps is even harder. Using SQL date functions requires every query to involve a conversion from the timestamp to a datetime:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>select date(from_unixtime(created_at))\r\nfrom packages\r\n-- vs\r\nselect date(created_at)\r\nfrom packages<\/code><\/pre>\r\n\r\n\r\n\r\n<p>Don\u2019t store the year, month, and day in separate columns. This will make every time series query much harder to write, and will prevent most novice SQL users from being able to use the date information in this table.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>select date(created_year || '-' \r\n  || created_month || '-' \r\n  || created_day)\r\n-- vs\r\nselect date(created_at)<\/code><\/pre>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">7. UTC, always UTC<\/h2>\r\n\r\n\r\n\r\n<p>Using a timezone other than <a href=\"https:\/\/en.wikipedia.org\/wiki\/Coordinated_Universal_Time\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">UTC<\/a> will cause endless problems. Great tools (including Sisense for Cloud Data Teams) have all the functionality you need you convert the data from UTC to your current timezone. In Sisense, it\u2019s as easy as adding :pst to convert to from UTC to Pacific Time:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>select [created_at:pst], email_address\r\nfrom users<\/code><\/pre>\r\n\r\n\r\n\r\n<p>The database\u2019s time zone should be UTC, and all datetime columns should be types that strip time zones (e.g. <strong>timestamp without time zone<\/strong>).<\/p>\r\n\r\n\r\n\r\n<p>If your database\u2019s time zone is not UTC, or you have a mix of UTC and non-UTC datetimes in your database, time series analysis will be a lot harder.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">8. Have one source of truth<\/h2>\r\n\r\n\r\n\r\n<p>There should only ever be one source of truth for a piece of data. Views and rollups should be labeled as such. This way consumers of that data will know there is a difference between the data they are using and the raw truth.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>select *\r\nfrom daily_usage_rollup<\/code><\/pre>\r\n\r\n\r\n\r\n<p>Leaving legacy columns around like user_id, user_id_old, user_id_v2 can become an endless source of confusion. Be sure to drop abandoned tables and unused columns during regular maintenance.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">9. Prefer tall tables without JSON columns<\/h2>\r\n\r\n\r\n\r\n<p>You don\u2019t want to have super-wide tables. If there\u2019s more than a few dozen columns and some of them are named sequentially (e.g. answer1, answer2, answer3), you\u2019re going to have a bad time later.<\/p>\r\n\r\n\r\n\r\n<p>Pivot the table into a schema that doesn\u2019t have duplicated columns &#8211; this schema shape will be a lot easier to query. For example, getting the number of completed answers for a survey:<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>select\r\n  sum(\r\n    (case when answer1 is not null\r\n      then 1 else 0 end) +\r\n    (case when answer2 is not null\r\n      then 1 else 0 end) +\r\n    (case when answer3 is not null\r\n      then 1 else 0 end)\r\n  ) as num_answers\r\nfrom surveys\r\nwhere id = 123\r\n-- vs\r\nselect count(response)\r\nfrom answers\r\nwhere survey_id = 123<\/code><\/pre>\r\n\r\n\r\n\r\n<p>For analysis queries, extracting data from JSON columns can greatly degrade a query\u2019s performance. While there are a lot of great reasons to use JSON columns in production, there aren\u2019t for analysis. Aggressively schematize JSON columns into the simpler data types to make analysis a lot easier and faster.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">10. Don&#8217;t over-normalize<\/h2>\r\n\r\n\r\n\r\n<p>Dates, zip codes, and countries don\u2019t need their own tables with foreign key lookups. If you do that, every query ends up with a handful of the same joins. It creates a lot of duplicated SQL and a lot of extra work for the database.<\/p>\r\n\r\n\r\n\r\n<pre class=\"wp-block-code\"><code>select\r\n  dates.d,\r\n  count(1)\r\nfrom users\r\n  join dates on users.created_date_id = dates.id\r\ngroup by 1\r\n-- vs\r\nselect\r\n  date(created_at),\r\n  count(1)\r\nfrom users\r\ngroup by 1<\/code><\/pre>\r\n\r\n\r\n\r\n<p>Tables are for first class objects that have a lot of their own data. Everything else can be additional columns on a more important object.<\/p>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading\">Better schemas await!<\/h2>\r\n\r\n\r\n\r\n<p>Armed with these rules, your next table or warehouse will be easier to query for both you and new team members as you expand.<\/p>\r\n\r\n\r\n","protected":false},"excerpt":{"rendered":"<p>There are a lot of decisions to make when creating new tables and data warehouses. Some that seem inconsequential at the time end up causing you and your users pain for the life of the database. We\u2019ve worked with thousands&#8230;<\/p>\n","protected":false},"author":4,"featured_media":22435,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_searchwp_excluded":"","footnotes":"","_links_to":"","_links_to_target":""},"categories":[44],"tags":[472],"application":[10],"buyer-role":[],"buyer-stage":[],"department":[],"industry":[],"topic":[73],"class_list":["post-6901","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tech-talk","tag-data-team","application-cloud-data-teams","topic-sql-superstar"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v23.5 (Yoast SEO v23.8) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>10 Rules for a Better SQL Schema | Sisense<\/title>\n<meta name=\"description\" content=\"After countless hours of reading and writing queries, we\u2019ve seen almost everything. Here are our top 10 rules for creating pain-free schemas.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.sisense.com\/blog\/better-sql-schema\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"10 rules for a better SQL schema\" \/>\n<meta property=\"og:description\" content=\"There are a lot of decisions to make when creating new tables and data warehouses. Some that seem inconsequential at the time end up causing you and your\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.sisense.com\/blog\/better-sql-schema\/\" \/>\n<meta property=\"og:site_name\" content=\"Sisense\" \/>\n<meta property=\"article:published_time\" content=\"2023-06-15T04:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-10-23T05:06:55+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/cdn.sisense.com\/wp-content\/uploads\/pd-blog-yoast-10-rules-better-schema-min.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"628\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Sisense Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/cdn.sisense.com\/wp-content\/uploads\/pd-blog-yoast-10-rules-better-schema-min.jpg\" \/>\n<meta name=\"twitter:creator\" content=\"@sisense\" \/>\n<meta name=\"twitter:site\" content=\"@sisense\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Sisense Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.sisense.com\/blog\/better-sql-schema\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.sisense.com\/blog\/better-sql-schema\/\"},\"author\":{\"name\":\"Sisense Team\",\"@id\":\"https:\/\/www.sisense.com\/#\/schema\/person\/e70aa3a7bbc471e4b7b8c5a7d2b36115\"},\"headline\":\"10 rules for a better SQL schema\",\"datePublished\":\"2023-06-15T04:00:00+00:00\",\"dateModified\":\"2024-10-23T05:06:55+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.sisense.com\/blog\/better-sql-schema\/\"},\"wordCount\":1327,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.sisense.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.sisense.com\/blog\/better-sql-schema\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/cdn.sisense.com\/wp-content\/uploads\/2024\/09\/15.png\",\"keywords\":[\"data team\"],\"articleSection\":[\"Tech Talk\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.sisense.com\/blog\/better-sql-schema\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.sisense.com\/blog\/better-sql-schema\/\",\"url\":\"https:\/\/www.sisense.com\/blog\/better-sql-schema\/\",\"name\":\"10 Rules for a Better SQL Schema | Sisense\",\"isPartOf\":{\"@id\":\"https:\/\/www.sisense.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.sisense.com\/blog\/better-sql-schema\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.sisense.com\/blog\/better-sql-schema\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/cdn.sisense.com\/wp-content\/uploads\/2024\/09\/15.png\",\"datePublished\":\"2023-06-15T04:00:00+00:00\",\"dateModified\":\"2024-10-23T05:06:55+00:00\",\"description\":\"After countless hours of reading and writing queries, we\u2019ve seen almost everything. Here are our top 10 rules for creating pain-free schemas.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.sisense.com\/blog\/better-sql-schema\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.sisense.com\/blog\/better-sql-schema\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.sisense.com\/blog\/better-sql-schema\/#primaryimage\",\"url\":\"https:\/\/cdn.sisense.com\/wp-content\/uploads\/2024\/09\/15.png\",\"contentUrl\":\"https:\/\/cdn.sisense.com\/wp-content\/uploads\/2024\/09\/15.png\",\"width\":1200,\"height\":700,\"caption\":\"15\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.sisense.com\/blog\/better-sql-schema\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.sisense.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"10 rules for a better SQL schema\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.sisense.com\/#website\",\"url\":\"https:\/\/www.sisense.com\/\",\"name\":\"Sisense\",\"description\":\"Build your business with anywhere-analytics\",\"publisher\":{\"@id\":\"https:\/\/www.sisense.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.sisense.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.sisense.com\/#organization\",\"name\":\"Sisense\",\"url\":\"https:\/\/www.sisense.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.sisense.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/cdn.sisense.com\/wp-content\/uploads\/sisense-yoast-og.jpg\",\"contentUrl\":\"https:\/\/cdn.sisense.com\/wp-content\/uploads\/sisense-yoast-og.jpg\",\"width\":1200,\"height\":600,\"caption\":\"Sisense\"},\"image\":{\"@id\":\"https:\/\/www.sisense.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/sisense\",\"https:\/\/www.linkedin.com\/company\/sisense\",\"https:\/\/github.com\/sisense\/\"],\"description\":\"Sisense accelerates product innovation through AI\/ML capabilities. Our global analytics platform lets customers drive better, faster decisions for their business and end users.\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.sisense.com\/#\/schema\/person\/e70aa3a7bbc471e4b7b8c5a7d2b36115\",\"name\":\"Sisense Team\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.sisense.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/213e415f47bc3c7f0155a0755b1cea8c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/213e415f47bc3c7f0155a0755b1cea8c?s=96&d=mm&r=g\",\"caption\":\"Sisense Team\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"10 Rules for a Better SQL Schema | Sisense","description":"After countless hours of reading and writing queries, we\u2019ve seen almost everything. Here are our top 10 rules for creating pain-free schemas.","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:\/\/www.sisense.com\/blog\/better-sql-schema\/","og_locale":"en_US","og_type":"article","og_title":"10 rules for a better SQL schema","og_description":"There are a lot of decisions to make when creating new tables and data warehouses. Some that seem inconsequential at the time end up causing you and your","og_url":"https:\/\/www.sisense.com\/blog\/better-sql-schema\/","og_site_name":"Sisense","article_published_time":"2023-06-15T04:00:00+00:00","article_modified_time":"2024-10-23T05:06:55+00:00","og_image":[{"width":1200,"height":628,"url":"https:\/\/cdn.sisense.com\/wp-content\/uploads\/pd-blog-yoast-10-rules-better-schema-min.jpg","type":"image\/jpeg"}],"author":"Sisense Team","twitter_card":"summary_large_image","twitter_image":"https:\/\/cdn.sisense.com\/wp-content\/uploads\/pd-blog-yoast-10-rules-better-schema-min.jpg","twitter_creator":"@sisense","twitter_site":"@sisense","twitter_misc":{"Written by":"Sisense Team","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.sisense.com\/blog\/better-sql-schema\/#article","isPartOf":{"@id":"https:\/\/www.sisense.com\/blog\/better-sql-schema\/"},"author":{"name":"Sisense Team","@id":"https:\/\/www.sisense.com\/#\/schema\/person\/e70aa3a7bbc471e4b7b8c5a7d2b36115"},"headline":"10 rules for a better SQL schema","datePublished":"2023-06-15T04:00:00+00:00","dateModified":"2024-10-23T05:06:55+00:00","mainEntityOfPage":{"@id":"https:\/\/www.sisense.com\/blog\/better-sql-schema\/"},"wordCount":1327,"commentCount":0,"publisher":{"@id":"https:\/\/www.sisense.com\/#organization"},"image":{"@id":"https:\/\/www.sisense.com\/blog\/better-sql-schema\/#primaryimage"},"thumbnailUrl":"https:\/\/cdn.sisense.com\/wp-content\/uploads\/2024\/09\/15.png","keywords":["data team"],"articleSection":["Tech Talk"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.sisense.com\/blog\/better-sql-schema\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.sisense.com\/blog\/better-sql-schema\/","url":"https:\/\/www.sisense.com\/blog\/better-sql-schema\/","name":"10 Rules for a Better SQL Schema | Sisense","isPartOf":{"@id":"https:\/\/www.sisense.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.sisense.com\/blog\/better-sql-schema\/#primaryimage"},"image":{"@id":"https:\/\/www.sisense.com\/blog\/better-sql-schema\/#primaryimage"},"thumbnailUrl":"https:\/\/cdn.sisense.com\/wp-content\/uploads\/2024\/09\/15.png","datePublished":"2023-06-15T04:00:00+00:00","dateModified":"2024-10-23T05:06:55+00:00","description":"After countless hours of reading and writing queries, we\u2019ve seen almost everything. Here are our top 10 rules for creating pain-free schemas.","breadcrumb":{"@id":"https:\/\/www.sisense.com\/blog\/better-sql-schema\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.sisense.com\/blog\/better-sql-schema\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.sisense.com\/blog\/better-sql-schema\/#primaryimage","url":"https:\/\/cdn.sisense.com\/wp-content\/uploads\/2024\/09\/15.png","contentUrl":"https:\/\/cdn.sisense.com\/wp-content\/uploads\/2024\/09\/15.png","width":1200,"height":700,"caption":"15"},{"@type":"BreadcrumbList","@id":"https:\/\/www.sisense.com\/blog\/better-sql-schema\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.sisense.com\/"},{"@type":"ListItem","position":2,"name":"10 rules for a better SQL schema"}]},{"@type":"WebSite","@id":"https:\/\/www.sisense.com\/#website","url":"https:\/\/www.sisense.com\/","name":"Sisense","description":"Build your business with anywhere-analytics","publisher":{"@id":"https:\/\/www.sisense.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.sisense.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.sisense.com\/#organization","name":"Sisense","url":"https:\/\/www.sisense.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.sisense.com\/#\/schema\/logo\/image\/","url":"https:\/\/cdn.sisense.com\/wp-content\/uploads\/sisense-yoast-og.jpg","contentUrl":"https:\/\/cdn.sisense.com\/wp-content\/uploads\/sisense-yoast-og.jpg","width":1200,"height":600,"caption":"Sisense"},"image":{"@id":"https:\/\/www.sisense.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/sisense","https:\/\/www.linkedin.com\/company\/sisense","https:\/\/github.com\/sisense\/"],"description":"Sisense accelerates product innovation through AI\/ML capabilities. Our global analytics platform lets customers drive better, faster decisions for their business and end users."},{"@type":"Person","@id":"https:\/\/www.sisense.com\/#\/schema\/person\/e70aa3a7bbc471e4b7b8c5a7d2b36115","name":"Sisense Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.sisense.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/213e415f47bc3c7f0155a0755b1cea8c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/213e415f47bc3c7f0155a0755b1cea8c?s=96&d=mm&r=g","caption":"Sisense Team"}}]}},"_links":{"self":[{"href":"https:\/\/www.sisense.com\/wp-json\/wp\/v2\/posts\/6901"}],"collection":[{"href":"https:\/\/www.sisense.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.sisense.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.sisense.com\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.sisense.com\/wp-json\/wp\/v2\/comments?post=6901"}],"version-history":[{"count":1,"href":"https:\/\/www.sisense.com\/wp-json\/wp\/v2\/posts\/6901\/revisions"}],"predecessor-version":[{"id":23092,"href":"https:\/\/www.sisense.com\/wp-json\/wp\/v2\/posts\/6901\/revisions\/23092"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.sisense.com\/wp-json\/wp\/v2\/media\/22435"}],"wp:attachment":[{"href":"https:\/\/www.sisense.com\/wp-json\/wp\/v2\/media?parent=6901"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.sisense.com\/wp-json\/wp\/v2\/categories?post=6901"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.sisense.com\/wp-json\/wp\/v2\/tags?post=6901"},{"taxonomy":"application","embeddable":true,"href":"https:\/\/www.sisense.com\/wp-json\/wp\/v2\/application?post=6901"},{"taxonomy":"buyer-role","embeddable":true,"href":"https:\/\/www.sisense.com\/wp-json\/wp\/v2\/buyer-role?post=6901"},{"taxonomy":"buyer-stage","embeddable":true,"href":"https:\/\/www.sisense.com\/wp-json\/wp\/v2\/buyer-stage?post=6901"},{"taxonomy":"department","embeddable":true,"href":"https:\/\/www.sisense.com\/wp-json\/wp\/v2\/department?post=6901"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/www.sisense.com\/wp-json\/wp\/v2\/industry?post=6901"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.sisense.com\/wp-json\/wp\/v2\/topic?post=6901"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}