Cross-posted from "What would be the best way to store the country of a user in SQL?" by @lena@gregtech.eu in !learn_programming@programming.dev


I use Gorm. This is the current code:

package main

import (
	"fmt"
	"log"

	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

type Env struct {
	DB     *gorm.DB
	Logger *log.Logger
}

type User struct {
	ID           uint
	Username     string
	Name         string
	Email        string
	PasswordHash string
	Country      string //should probably be a foreign key of another table
}

func initDB() {
	env := &Env{}
	db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{})
	if err != nil {
		fmt.Printf("Error opening database: %v", err)
		return
	}
	env.DB = db
	env.DB.AutoMigrate(&User{})

}

func main() {
	initDB()
}

As you can see in the comment in the code, I assume the best way would be to have a table of countries and then assign each user to one via a foreign key. However, it seems a bit cumbersome to manually create a list of all countries. Is there a better way to do this?

all 28 comments

sorted by: hot top controversial new old
[–] 60 points 1 year ago (4 children)
  • [–] [S] 6 points 1 year ago (3 children)

    Am I supposed to make an SQL statement that puts these country codes into a table, along with the country's name? There's probably a better way. Maybe I could make a new entry for every unique country a user is from

  • source
  • parent
  • hideshow 3 child comments
  • [–] 8 points 1 year ago

    not sure I understand the distinction between the "am I supposed to" and "maybe I could" parts?

    You should create a table of all countries, you can just copy that from the above link. Then you reference that table with a foreign key in your users table.

  • source
  • parent
  • [–] 35 points 1 year ago (7 children)

    Store a jpg of the country's flag as binary

  • source
  • hideshow 7 child comments
  • [–] 11 points 1 year ago

    This is the only real way to do it, the other solutions involve "standards" which more often than not aren't all encompassing. Make sure that any user input of a country is just them uploading the jpg of their home country without any sort of validationbecausee everyone is loyal to their home country.

  • source
  • parent
  • [–] 3 points 1 year ago (2 children)

    You're supposed to use PNG for images of that sort, you fucking barbarian.

  • source
  • parent
  • hideshow 2 child comments
  • [–] 19 points 1 year ago

    An important question no-one has asked yet is, What do you need that info for?

  • source
  • [–] 10 points 1 year ago (1 child)

    I store iso country codes and use them as the primary key in a countries table.

  • source
  • hideshow 1 child comment
  • [–] 7 points 1 year ago

    Same for using an "almost non-changing" standard, i.e. either ISO or RFC. And write a script to update the data or tables if something wrong changes (like Russia disappearing because it has been invaded by Belgium), you never know what might happen politically.

  • source
  • parent
  • [–] 4 points 1 year ago

    I'd store it as a string (ISO code), pretty much every programming language has icu data for country names.

    If you need more data later, it's very simple to migrate.

  • source
  • [–] 2 points 1 year ago

    I'm a fan of CountryCode being a string column that's a FK to a reference table of Country values.

    Same for State/Province.

  • source
  • [–] 0 points 1 year ago*

    It will depend upon other things you might want to do with it in the future.
    If you want the record to stay "correct" in the future, you might want to have a separate entry for nationality information, which will be a 1-to-1 mapping with the other table you make for it. Why? ...

    • in the nationality information, along with the country code (for which you want to allow 3 character codes for forward compatibility), the date at which the the information was given in the form
    • if possible, also include the date at which the nationality was provided (as in, provided to the user by the nation)

    This should help determine what kind of change may occur in case of changes in the political landscape in the future, without you requiring to re-ask the form-filler.


    Inspired by https://flightaware.engineering/falsehoods-programmers-believe-about-aviation/
    And I am going to consider this stuff every time I make a database schema.

    Stuff in the real world is subject to change, so instead of only storing the provided data as you asked for, make a ledger for events. And someone submitting a forms, will be another event.

    This way, you get the flexibility to verify the provided data in the future, using information that you will have in the future, but don't have at the time the data was provided.

    Of course, this is only needed if it is needed.

  • source
  • [–] -3 points 1 year ago (8 children)

    GPS coordinates. Much more efficient than storing country, province, city, address, and postal code. Let the front end handle the rest.

  • source
  • hideshow 8 child comments
  • [–] 7 points 1 year ago (4 children)

    GPS? Absolutely insufficient. What about the people on the ISS? Or when the moon base is established? Ever thought of that? No. You think only of yourself.

  • source
  • parent
  • hideshow 4 child comments
  • [–] 2 points 1 year ago

    Simple, add additional columns for the frame of reference (e.g. Earth) and elevation. You could even store space coordinates using Sun as a reference point (though you would need to update data regularly for spacecraft as they move of course).

  • source
  • parent
  • [–] 1 point 1 year ago (2 children)

    GPS: Galactic Positioning System

    Just suppose you are not selling the software outside of the galaxy and you will have to update your database (and transform and migrate all the data) when the 2 galaxy positioning system is formed.

  • source
  • parent
  • hideshow 2 child comments
  • [–] 4 points 1 year ago* (2 children)

    Terrible idea for a few reasons.

    • The example in the OP does not need anything but the country. GPS coordinates are less efficient than ISO codes
    • GPS coordinates don't map 1:1 to countries or even street addresses. There are infinite different coordinates for each address, and it's very non-trivial to match one to another. Comparing whether two records with country codes are in the same country is trivial. Doing the same with two GPS coordinates is very difficult.
    • GPS coordinates might be more exact than accurate. This is a surprisingly common issue: you start out only needing a country, so you put some arvitrary GPS position (e.g. the center of the country) into the GPS coordinates. Later a new requirement arises that means you now need street addresses. Now all old entries point so some random house in the middle of the country, and there's no easy way to differentiate these false locations from real ones.

    I guess you meant that as a joke, but people are really doing this and it leads to actual problems.

    I saw a news report a while ago about something like that being done in a database for people with outstanding debt. If the address of the debtor wasn't known, they just put "US" in the form, and the program automatically entered the centre of the US as the coordinates.

    Sucks for the family that lives there because they constantly get threatening mail and even house visits from angry lenders who want their money back. People even vandalized their house and car because they believed that their debtors lived in that house.

  • source
  • parent
  • hideshow 2 child comments