Quick Answers: What is the UUID column type good for and what exactly is a UUID?

The question has come up a few times recently about what UUIDs are and what they’re good for. In this quick answers post I explain what they are and provide reference links to further material, as well as a Hasura Short video to implementation and use in Postgres & Hasura.

A Hasura Bit

“A Hasura Bit – What sit he UUID column type good for and what exactly is a UUID?” video.

UUID

UUID stands for a universally unique identifier. Another term which is common for a UUID, is the GUID, or globally unique identifier, which is the common term Microsoft created for their UUIDs. Just know, that a GUID is a UUID, it’s just company naming convention vs the standard industry naming convention.

UUIDs are standardized by the Open Software Foundation (OSF) as part of the Distributed Computer Environment (DCE). Specifically UUID are designed and used from an USO/IEC spec, which if you’d like to know more about the standards they’re based on check out the Wikipedia page @ https://en.wikipedia.org/wiki/Universally_unique_identifier

UUID Format

The canonical textual representation, the 16 octets of a UUID are represented as 32 hexadecimal (base-016) digits. They’re displayed across five groups separated by hyphens in 8-4-4-4-12 format. Even though there are 32 hexadecimal digits, this makes a total of 36 characters for format display. If storing as a string for example, the string needs to be able to hold 36 characters.

Uses for a UUID

The first key use case for a UUID is to have something generate the UUID to use it as a completely unique value for use with a subset of related data. UUIDs are prefect for primary keys in a database, or simply any type of key to ensure uniqueness across a system.

UUIDs can be generated from many different origin points too without any significant concern for collision (i.e. duplicate UUIDs). For example, the database itself has database functions that enable the generation of a UUID at time of a data row’s insertion, as a default value. This means a client inserting data wouldn’t need to generate that UUID. However this can be flipped over to the client side as a responsibility and the client side development stack (i.e. like Go UUID generation) can generate the UUID. Which then enables the creation of a primary key entity being created with a UUID as the primary key, that can then be used to create what would be foreign key items and so on down the chain of a relationship. Then once all of these are created on the client side they can all be inserted in a batch, and even if ordered appropriately can be made transactional to ensure the integrity of the data.

Learning Go Episode 3 – More Data Types, Casting, Rendering an SVG file, and writing to Files.

Episode Post & Video Links:  1, 2, 3 (this post), 4, 5, 6, 7, and 8. Non-linked are in the works! Videos available now on Youtube however, so check em’ out!

Episode 3 of my recurring “Learning Go” Saturday stream really got more into the particulars of Go data types including integers, strings, more string formatting verbs, concatenation, type casting, and lots of other pedantic details. In the episode I also delve into some OBS details with the audience, and we get the Twitch interface I’ve setup a bit more streamlined for easier readability. Overall, I think it’s looking much better than just the last episode! Hats off to the conversational assist from the audience.

Here’s the play by play of what was covered in episode 3 with the code in gists plus the repo is available on Github. Video below the timeline.

Timeline

0:00 Intro
6:08 The point I fix the sound. Just skip that first bit!
6:24 Re-introducing the book I’m using as a kind of curriculum guide for these go learning sessions.
7:44 Quick fix of the VM, a few updates, discussion of Goland updates, and fixing the Material Theme to a more visually less caustic theme. Also showing where it is in the IDE.
9:52 Getting into the learning flow, starting a new project with Go 1.11.4 using the Goland IDE new project dialog.


package main
import (
"fmt"
"math"
"strconv"
)
func main() {
var someInt int
var anotherValue int64
thisValue := 45
thisVAlue, thatValue, someValue := 20, 23, 15
someInt = thisVAlue
anotherValue = 64
const knownSet = 7.12904
const anotherKnown = 9.10347
for x := 0; x < 20; x++ {
fmt.Printf("x = %d e = %8.3f\n", x, math.Exp(float64(x)))
}
fmt.Printf("Known Set and Another Known: %2.7f, %2.7f", knownSet, anotherKnown)
fmt.Printf("The values: %6d, %6d, %6d, and %s.\n", thisValue, thisVAlue, thatValue, strconv.Itoa(someValue))
fmt.Printf("Other values: %4d, %4d.\n", someInt, anotherValue)
fmt.Printf("Function doThings: %6d\n", doThings(thisVAlue, thisValue))
fmt.Printf("Function doMoreThings: %s", doMoreThings(someInt, int(anotherValue), "Adron"))
}
func doThings (valueOne int, valueTwo int) int64 {
result := valueOne * valueTwo
return int64(result)
}
func doMoreThings (valueOne int, valueTwo int, name string) string {
result := valueTwo + valueOne * 10
return "The result added and exponentially multiplied for you " + name + " this: " + strconv.Itoa(result)
}

view raw

main.go

hosted with ❤ by GitHub

10:50 Creating the Github repo for learning-go-episode-3.
12:14 Setting up the initial project and CODING! Finally getting into some coding. It takes a while when we do it from nothing like this, but it’s a fundamentally important part of starting a project!
13:04 From nothing, creating the core basic elements of a code file for go with main.go. In this part I start showing the various ways to declare types, such as int and int64 with options on style.
14:14 Taking a look at printing out the various values of the variables using formatter verbs via the fmt.Printf function.
17:00 Looking at converting values from one type to another type. There are a number of ways to do this in Go.

I also, just recently, posted a quick spot video and code (blog entry + code) on getting the minimum and maximum value in Go for a number of types. This isn’t the course video, just a quick spot. Keep reading for the main episode below.

18:16 Oh dear the mouse falls on the ground. The ongoing battle of streaming, falling objects! But yeah, I get into adding a function – one of the earlier functions being built in the series – and we add a signature with a return int64 value. I continue, with addition of another function and looking at specifics of the signature.
25:50 Build this code and take a look at the results. At this point, some of the formatting is goofed up so I take a look into the formatter verbs to figure out what should be used for the output formatting.
33:40 I change a few things and take a look at more output from the various calculations that I’ve made, showing how various int, int64, and related calculations can be seen.
37:10 Adding a constant, what it is, and when and where and why to declare something as a constant.
38:05 Writing out another for loop for output results of sets.
42:40 A little git work to create a branch, update the .gitignore, and push the content to github. Repo is here btw: https://github.com/Adron/learning-go-episode-3

At this point I had to take a short interruption to get my ssh keys setup for this particular VM so I could push the code! I snagged just a snippet of the video and made a quick spot video out of it too. Seems a useful thing to do.

47:44 Have to add a new ssh key for the virtual machine to github, so this is a good little snippet of a video showing how that is done.
56:38 Building out a rendering of an SVG file to build a graphic. The complete snippet is below, watch the video for more details, troubleshooting, and working through additions and refactoring of the code.


package main
import (
"fmt"
"io/ioutil"
"math"
"strconv"
)
const (
width, height = 600, 600
cells = 100
xyrange = 30.0
xyscale = width / 2 / xyrange
zscale = height * 0.4
angle = math.Pi / 6
)
var sin30, cos30 = math.Sin(angle), math.Cos(angle)
func main() {
var outputResult string
outputResult = "<svg xmlns='http://www.w3.org/2000/svg&#39; " +
"style='stroke: blue; fill: white; stroke-width: 0.7' " +
"width='" + strconv.Itoa(width) + "' height='" + strconv.Itoa(height) + "'>"
for i := 0; i < cells; i++ {
for j := 0; j < cells; j++ {
ax, ay := corner(i+1, j)
bx, by := corner(i, j)
cx, cy := corner(i, j+1)
dx, dy := corner(i+1, j+1)
outputResult = outputResult + "<polygon points='" +
ax + "," + ay +
bx + "," + by +
cx + "," + cy +
dx + "," + dy +
"'/>\n"
}
}
outputResult = outputResult + "</svg>"
fmt.Printf(outputResult)
err := ioutil.WriteFile("surface-plot.svg", []byte(outputResult), 0644)
if err != nil {
fmt.Printf("Error: %s", err)
}
}
func corner(i, j int) (string, string) {
x := xyrange * (float64(i)/cells 0.5)
y := xyrange * (float64(j)/cells 0.5)
z := f(x, y)
sx := width/2 + (xy)*cos30*xyscale
sy := height/2 + (x+y)*sin30*xyscale z*zscale
xResult := strconv.FormatFloat(sx, 'f', 1, 64)
yResult := strconv.FormatFloat(sy, 'f', 1, 64)
return xResult, yResult
}
func f(x, y float64) float64 {
r := math.Hypot(x, y)
return math.Sin(r)
}

view raw

main.go

hosted with ❤ by GitHub

1:15:32 We begin the mission of bumping up the font size in Goland. It’s a little tricky but we get it figured out.
1:33:20 Upon realization, we need to modify for our work, that this outputs directly to a file instead of just the console. Things will work better that way so I work into the code a write out to file.
1:40:05 Through this process of changing it to output to file, I have to work through additional string conversions, refactoring, and more. There’s a lot of nuance and various things to learn during this section of the video, albeit a little slow. i.e. LOTS of strconv usage.
2:01:24 First view of the generated SVG file! Yay! Oh dear!
2:09:10 More troubleshooting to try and figure out where the math problem is!
2:22:50 Wrapping up with the math a little off kilter, but sort of fixed, I move on to getting a look into the build but also pushing each of the respective branches on github. Repo is here btw: https://github.com/Adron/learning-go-episode-3

The Nuances of Go: Go Program Structure

Talking About Types, Variables, Pointers, and More

In my endeavor to get more of the specifics of Go figured out, I’ve been diving a bit more in depth to each of the specific features, capabilities, and characteristics of the language. I’ll be doing the same for Cassandra over the coming months and producing a blog entry series about it. This new series however is about Go, and this first in the series is about types, variables, pointers, and naming of these things. Enjoy.

Reserved Words, Keywords & Related Systemic Parts of Go

First off let’s talk about the reserved words in Go. The list includes 25 keywords that can’t be used as variables or names of functions or anything like that. This list includes:

if import interface map
select return range package
struct switch type var
for func go goto
default defer else fallthrough
case const chan continue
break

Beyond these 25 keywords there are also some predeclared names that can be but usually shouldn’t be used for naming. These include:

Constants

true false iota nil

Types

int int8 int16 int32
int64 uint uint8 uint16
uint32 uint64 uintptr float32
float64 complex128 complex64 bool
byte rune string error

Functions

make len cap new
append copy close delete
complex real imag panic
recover

When declaring an entity within a function, it’s scope is limited to that function. When declaring it outside of the function it is available to the contents of the package it is declared inside of. The case of the first letter also has the effect of allowing access within or across package boundaries. If the name begins with an upper case character it is exported for other packages. Package names themselves are always lower case however.

Camel Casing

It’s also important to know about the emphasis and standard within Go to use camel casing. Except it appears that for acronyms and such like; HTML, XML, JSON, or such things, it is routine to use names like HTMLthingy, XMLjunkHere, or rockStarJSON. Go is somewhat particular about these types of things, so it is extremely important to use the Go format standards. To help with this, there’s also the gofmt function, but it’s always good to just use the proper formatting during writing of the code anyway.

The Four Declarations

The four declarations are kind of like the four horsement, except not really. Forget that analogy as it was already going nowhere. The four declarations include:

var const type func

Here are some code samples of various declarations. First use of the func. In any new Go program there’s always the main() function. Declared like this.

[sourcecode language=”javascript”]
func main() {
// Stuff goes here.
}
[/sourcecode]

Another example of a function declaration with parameters passed and expected results to return. The signature works like func followed by the name of the function, then in parenthesis parameter name followed by its type, for as may parameters as is needed. Then after the parenthesis the type of the expected result of the function. Of course, if no result is expected to be returned, then there would be no tpe specified here. Just as if no parameters, the parenthesis would still be used but no parameters specified.

[sourcecode language=”javascript”]
func doSomeComputation(someValue float64, anotherFloaty float64) float64 {
return someValue * anotherFloat
}
[/sourcecode]

Using the var for declaration of variables looks like this.

[sourcecode language=”javascript”]
var f = 212.0
var result = 2 + 2
var celsius = (f – 32) * 5 / 9
[/sourcecode]

Variable types can be defined in this way. Using var keyword, followed by the variable name, then followed by its type, and then if desired assigned via = and then the specific value or function with a result to assign to the variable.

var name type = expression

Without an assignment, the variable is simply created with the intent of assigning a value later. Such as these variable declarations.

[sourcecode language=”javascript”]
var f float32
var result float64
var celsius float64
var someVariable int
var junk string
[/sourcecode]

A shorter version of the creation and assignment of variables looks like this. It however can only be used within a function.

name := expression

Actual use of this shorter version would look like this.

[sourcecode language=”javascript”]
f := 212.0
randomStuff := rand.Float64()
wordContent := “This is some character string nonsense.”
[/sourcecode]

One can also do some other tricks with this shorter method of assignment. Let’s say some variables are needed that will have integers assigned to them. You could set up the variables with values like this. I’ve noticed some get a bit confused about this and tuple assignments, this is not the same thing. This merely gives you three variables: k, l, and m and assigns the values 0, 1, and 2 to the respective variable.

[sourcecode language=”javascript”]
k, l, m := 0, 1, 2
[/sourcecode]

It’s also important to note, a short declaration doesn’t always declare all of the variables on the left-hand side. Some, if already declared in the same lexical block, it then acts as an assignment to the variables instead.

Declaring a constant value with const would look like this.

[sourcecode language=”javascript”]
const fahrenheitBoiling = 212.0
[/sourcecode]

Pointers

A variable holds a particular value, where as a pointer holds the address in memory of a particular value. Sometimes, it gets a bit difficult to mentally keep track of pointers, so let’s look at a few examples. First I’ll start with a plain old variable.

[sourcecode language=”javascript”]
someVariable := “The original value of this variable.”
[/sourcecode]

Then I’ll add another variable, which will point at the address and respective value of someVariable.

[sourcecode language=”javascript”]
someVariable := “The original value of this variable.”
anotherVariable := &someVariable
fmt.Println(*anotherVariable)
[/sourcecode]

In this situation what does the fmt.Println(*anotherVariable) function print out? The result would be “The original value of this variable.” because anotherVariable is a variable that points to the value of someVariable. Which means anotherVariable doesn’t take the resources that someVariable does, but merely points to it.

The reasoning here is, if you have variable for example that stores a very large value in memory. One can merely point to that data with a pointer and the large value doesn’t have to change it’s memory space. Imagine if that variable were a gigabyte of data and it had to be moved every time something needed referenced or calculated with it, with a pointer we don’t have to move it. It can be used in various ways without it getting shifted around.

Now if I take the pointer value anotherVariable and assign it a value, like this.

[sourcecode language=”javascript”]
*anotherVariable = “42”
[/sourcecode]

Then what happens? The pointer now is re-allocated and assigned the new value of “42”. It no longer references the address space of the pointer and instead now has the value 42 assigned to the variable.

The Fancy new Function

There’s also another function, a built-in one, that creates a variable. Using the expression new(type) will create an unnamed variable of type, initializes it, and returns the address of the value of type. In pointer speak, it’d be *type. Here are some examples.

[sourcecode language=”javascript”]
pinto := new(int)
fmt.Println(*pinto)
[/sourcecode]

This code will create a variable of type int, then initialize the value to zero since it is an int. Let’s say we want to actually give it a value after it’s created though. We could assign pinto like this.

[sourcecode language=”javascript”]
*pinto = 42
fmt.Println(*p)
[/sourcecode]

This will then print out the value 42, of type integer. Note, this new is just sugar, a syntactical convenience feature really. They can be useful however, and there are a few caveats that need to be noted. For example, check out this gotcha.

If I declare two new values using new.

[sourcecode language=”javascript”]
firstThing := new(int)
secondThing := new(int)
fmt.Println(firstThing == secondThing)
[/sourcecode]

In this case, the firstThing and secondThing don’t actually match, because the comparison is on the address space, and they’re different address spaces!

Alright, that’s it for now, just a few important nuances around how variables, pointers, and Go features work.