Efficiently organizing a 2D map in a SQL database using an optimized primary key structure

Currently, I am developing a small JavaScript game that relies on a map rendered from a collection of coordinates stored in a database. As I work on designing the database, I am contemplating between two methods to determine which one would be more preferable.

The world in my game is mapped to 1000x1000 tiles, with each coordinate pair (x,y) representing a unique tile with its own set of properties.

Given that this is my first time creating an object/database like this, my initial thought was to use the unique coordinate pair as the primary key. This method not only guarantees no collision but also provides a clear way of allocating the primary keys. For example, tile x: 844, y:444 would have an ID of 08440444. Would using this approach make it more computationally challenging to retrieve an X coordinate from a given ID compared to the alternative? Are there other ways to construct an ID from an [x,y] pair?

                                  ┌──────────────────┐                                    
                                  │   table: tiles   │                                    
                  ┌─────────────────┼──────────────────┼─────────────────┐                  
                  │               coord                ├     treasures    │                  
                  │                                   ├      people      │                  
                  │───┬──────              integer     │                  │                  
                  │             │─primary key           │ hasMany         │                  
                  │unique x,y coord│ relationship       │relationship     │                  
                  │             │                      │                  │                  
                  └─────────────────┴──────────────────┴─────────────────┘                  

or



                                ┌──────────────────┐                                     
                                │   table: tiles   │                                     
┌─────────────────┬────────────┼──────────────────┼─────────────────┬─────────────────┐
│        id       │        x     ├        y          │    treasures   │     people    │
│                 │                │                   │                │                │
├────────────────-┼────────────┼──────────────────┼──────────────────┼──────────────┤
│ int            │     int         │       int         │                  │                  │
│ primary key    │represents x│represents y│hasMany         │hasMany        │
│ autoincrementing│coordinate │ coordinate  │ relationship   │ relationship  │
│                 │                │                    │                  │
└────────────────-┴────────────┴──────────────────┴────────────────--┴──────────────┘

Answer №1

If you want your game engine to run smoothly, optimizing your database is key. Define a data structure that aligns with your clear tile "environment":

  • Opt for using smallint for Tile IDs instead of regular integer, saving 50% in storage and reducing network traffic.
  • Create a Primary Key from the tile IDs rather than using a serial data type or an extra column, unless it significantly benefits your data model. Consider utilizing a non-unique index on the tile IDs instead of a PK.

In many cases, having just "treasures" and "people" tables with 'x' and 'y' coordinates should be sufficient. Only introduce a "tiles" table if you require specific tile properties through a relationship like "has-a" or "is-a" (1-1). Avoid defining referential relationships between tables unless absolutely necessary, as they can be resource-intensive to maintain.

Here's a simplified setup you might consider:

CREATE TABLE tileproperties (
  x      smallint,
  y      smallint,
  prop1  integer,
  prop2  varchar,
  ...
);
CREATE INDEX idx_tileproperties ON tileproperties(x, y);

CREATE TABLE treasures (
  x      smallint,
  y      smallint,
  id     smallint, 
  t_type integer,  
  prop1  integer,
  prop2  varchar,
  ...
);
CREATE INDEX idx_treasures ON treasures(x, y, id);

CREATE TABLE people(
  x      smallint,
  y      smallint,
  id     smallint, 
  p_type integer,  
  prop1  integer,
  prop2  varchar,
  ...
);
CREATE INDEX idx_people ON people(x, y, id);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Breaking Down a Lengthy AngularJS Controller into Modular Components

I'm diving into developing my first Angular app, and I'm struggling with breaking down the code into more manageable chunks. Right now, all of my functionality is packed into one lengthy controller which is causing issues when it comes to data bi ...

Transform an array into an object utilizing only underscore

I'm currently learning about underscore and came across a task that I could use some assistance with. I have an array containing objects like the following: [ // ... { "type": "presence", "params": { "i ...

Can data be fetched from a local port using either Javascript or ASP.NET?

I have created the code below to broadcast data in a Windows application using C#. UdpClient server = new UdpClient("127.0.0.1", 9050); string welcome = "Hello, are you there?"; data = Encoding.ASCII.GetBytes(welcome); ...

How can I retrieve the height of a hidden image in Internet Explorer?

I am encountering an issue with images that have been set to display:none. I am using javascript (document.getElementById('elem').height) to retrieve the height/width of these images. While this method works in most browsers, IE is reporting th ...

Transform the varchar data type into a date format with the pattern yyyy-mm-dd

My database field contains a varchar value 04 Jul 2016 12:00:00 AM. Is there a way to transform it into 2016-07-04 format? ...

Error: Invalid JSON Web Token structure

I am working on creating a middleware to authenticate users using JWT and cookies. After decrypting the cookie that was encrypted during the login process, I attempted to verify it using jwt.verify(). However, I encountered an error message: JsonWebTokenEr ...

Why is MySQLi not retrieving all the rows?

I am seeking assistance with the following issue: SELECT s.`uid` FROM `sessions` s (I had initially included a LEFT JOIN in the query, but removed it for debugging purposes) For reference, here is the full query: SELECT s.`uid`, u.`username`, u.`email` ...

Enhance your website visuals with jQuery Sparklines and CSS Transforms

I've incorporated jQuery Sparklines into an html page that I've resized using the transform: scale property. However, this adjustment has caused the jQuery Sparklines tooltip to appear in the incorrect location. For instance, consider the code sn ...

Inject props into a Component nested within a Higher-Order-Component (HOC)

In attempting to grasp the concept of creating a React Higher Order Component from this particular article, I find myself struggling to fully understand and utilize this HOC. interface PopupOnHoverPropType { hoverDisplay: string; } const WithPopupOnHov ...

Identify and track colored dots within an image using tracking.js

I'm working on creating a program that can tally the number of dots on dominoes in an image, such as the one shown here: https://i.sstatic.net/NKHXl.jpg My goal is to develop this functionality using JavaScript. I've attempted to learn how to u ...

Customize the field type in Kendo UI Grid based on specific row criteria

Dealing with a predicament that is proving to be quite challenging. I have a kendo grid that is being populated with data from a JSON file. The issue lies in the fact that the JSON file contains a field with varying types across different elements. Allow ...

Defining the NgRx root state key within the application state interface

Here is an example of a selector taken from the NgRx documentation: import { createSelector } from '@ngrx/store'; export interface FeatureState { counter: number; } export interface AppState { feature: FeatureState; } export const sel ...

Plotting only the initial and final point on Google Maps using API

I am currently working on a tracking application that utilizes the Geolocation and Google Maps API. The app is set up to track the user's position using the watchPosition() function. As of now, a new blue icon is displayed every time a new longitude a ...

Tips for displaying bar chart labels effectively with ChartJS

I am working on an Angular project and I would like to incorporate a barchart using ChartJS. The data for this chart can vary in size, sometimes being very large. One issue I have encountered is that when the number of data points is large, the labels ove ...

The functionality to redirect in Wordpress Contact Form 7 based on the value of a radio button selection does

For the past 5 hours, I have been diving deep into Contact Form 7 redirects that are based on values. Despite my efforts, I am unable to figure out why my code isn't functioning properly. Is there anyone who can spot the issue? Contact Form Radio But ...

Running a stored procedure using a string that mimics an array, with the values separated

Similar Question: Help with a sql search query using a comma delimitted parameter I am looking to create a stored procedure that can perform a select operation on a table with an input variable of type varchar(max). The input parameter should be able ...

Using npm to install packages with multiple package.json files

My current project includes a submodule with another submodule, each having their own package.json file. This is how I set up my project: |root ----|node_modules ----|package.json ----|someFolder ----|submodule_1 -------- |package.json -------- |someFold ...

Learn the process of utilizing Javascript to substitute additional texts with (...) in your content

I am facing a challenge with a text field that allows users to input text. I want to use JavaScript to retrieve the text from the textbox and display it in a paragraph. However, my issue is that I have set a character limit of 50. If a user exceeds this li ...

When I set a date for one variable, it causes another variable to be automatically updated as

let currentDate = lastDate; currentDate = new Date(currentDate.setDate(currentDate.getDate() + diffDays)); I only updated the value of currentDate, but why did the value of lastDate also change when I set the date for currentDate? ...

Merge JSON objects into an array

Is there a way to merge JSON objects when the initial object is: { "total": "2" } And the second one is: [ "player1": { "score": "100", "ping": "50" }, "player2": { "score": "100", "ping": "50" ...