Handling Single Table Design

Hi!

What would be the best practice way of handling a single table design, e.g. from Dynamo DB?
Suppose we have this example table “Cart”:

Id | SubType | Additional attributes ...
abc | Product_def | Milk (Name) | $1 (Price)
abc | Product_ghi | Coffee (Name) | $5 (Price)
abc | Member_jkl | Tanax (Username) | emailaddress@example.com (Email)
abc | DeliveryAddress_mno | Some Address 123 (Address)

Fetching a specific row, e.g. Id = "abc" && SubType = "Product_def" is easy, you can parse that as a product since you know it’s a product. But when fetching the full cart, i.e. Id = "abc", you’ll get multiple rows of different types with different attributes. Products has Name and Price whereas for instance Members has Username and Email.

I’ve seen a few ways that could work to parse these dynamic fields.
One way could be to have a large struct that has all possible available fields of all sub types, then you could have helper methods to help you get what sub type it is and then get a specific struct based on that.

type MyLargeStruct struct {
    Id string
    SubType string
    Name string
    Price string
    Username string
    Email string
    Address string
}

type Product struct {
    Id string
    SubType string
    Name string
    Price string
}

func (mls *MyLargeStruct) IsProduct() bool {
    return strings.HasPrefix(mls.SubType, "Product")
}

func (mls *MyLargeStruct) GetProduct() *Product {
    return &Product{ copy fields values to product here.. }
}

Another way could be to simply parse each result row to a var line map[string]interface{} and then based on if strings.HasPrefix(line["SubType"], "Product") you could marshal it to json, then unmarshal it to a specific Product struct.

Which one of these would you suggest? And are there more options that I haven’t thought of?
Thanks!

I see two options:

I think it is an anti pattern to use a relational database without actually using relations. If you want a single table design, use a DB and a client library that is build to support it.

Hi lutzhorn,

Thank you for your reply!
I agree with everything you said, and I’m already using a Dynamo DB client library (Go’s own library in the form of gocloud’s docstore).

My question is not how to fetch from the database but rather how to structure the Go structs (i.e. data entities) the best way for handling a single table design. As far as I know, no library does this built-in.

Maybe embedding types could be helpful.

package main

import (
	"fmt"
)

type Common struct {
	Id      string
	SubType string
}

type User struct {
	Common   Common
	Username string
	Email    string
	Address  string
}

func main() {
	user := User{Username: "john.doe", Common: Common{Id: "user-1", SubType: "User"}}
	fmt.Println(user)
}

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.