fix: replace uuid columns with rowid aliases
This commit is contained in:
@@ -42,7 +42,9 @@ module App::Controllers
|
||||
slug = @env.params.url["slug"]
|
||||
|
||||
link_data = nil
|
||||
Database.raw_query("SELECT id, url FROM links WHERE slug = (?) LIMIT 1", slug) do |result|
|
||||
# LIMIT 1 degrades performance on unique field searches
|
||||
# slug autoindex has better perormance than the covering index
|
||||
Database.raw_query("SELECT id, url FROM links WHERE slug = (?)", slug) do |result|
|
||||
if result.move_next
|
||||
link_data = {result.read(String), result.read(String)}
|
||||
end
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
-- +micrate Up
|
||||
-- SQL in section 'Up' is executed when this migration is applied
|
||||
-- 1. Create new users table with INTEGER PK
|
||||
CREATE TABLE users_new (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
api_key VARCHAR(64) UNIQUE NOT NULL,
|
||||
created_at INTEGER DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
updated_at INTEGER DEFAULT CURRENT_TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
-- Create a mapping table to track old and new user IDs
|
||||
CREATE TEMPORARY TABLE user_id_map (
|
||||
old_id TEXT,
|
||||
new_id INTEGER
|
||||
);
|
||||
|
||||
-- Insert users data and capture the mappings
|
||||
INSERT INTO users_new (name, api_key, created_at, updated_at)
|
||||
SELECT name, api_key, created_at, updated_at FROM users;
|
||||
|
||||
INSERT INTO user_id_map
|
||||
SELECT u.id, u_new.id
|
||||
FROM users u
|
||||
JOIN users_new u_new ON u_new.api_key = u.api_key;
|
||||
|
||||
-- 2. Create new links table with INTEGER PK
|
||||
CREATE TABLE links_new (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
slug VARCHAR(8) UNIQUE NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
created_at INTEGER DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
updated_at INTEGER DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
FOREIGN KEY (user_id) REFERENCES users_new(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Create a mapping table for links
|
||||
CREATE TEMPORARY TABLE link_id_map (
|
||||
old_id TEXT,
|
||||
new_id INTEGER
|
||||
);
|
||||
|
||||
-- Insert links data with new user_id foreign keys
|
||||
INSERT INTO links_new (user_id, slug, url, created_at, updated_at)
|
||||
SELECT
|
||||
(SELECT new_id FROM user_id_map WHERE old_id = l.user_id),
|
||||
l.slug,
|
||||
l.url,
|
||||
l.created_at,
|
||||
l.updated_at
|
||||
FROM links l;
|
||||
|
||||
-- Create the mapping for links
|
||||
INSERT INTO link_id_map
|
||||
SELECT l.id, l_new.id
|
||||
FROM links l
|
||||
JOIN links_new l_new ON l_new.slug = l.slug AND l_new.url = l.url;
|
||||
|
||||
-- 3. Create new clicks table with INTEGER PK
|
||||
CREATE TABLE clicks_new (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
link_id INTEGER NOT NULL,
|
||||
user_agent TEXT,
|
||||
browser TEXT,
|
||||
os TEXT,
|
||||
referer TEXT,
|
||||
country TEXT,
|
||||
created_at INTEGER DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
updated_at INTEGER DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
FOREIGN KEY (link_id) REFERENCES links_new(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Insert clicks data with new link_id foreign keys
|
||||
INSERT INTO clicks_new (link_id, user_agent, browser, os, referer, country, created_at, updated_at)
|
||||
SELECT
|
||||
(SELECT new_id FROM link_id_map WHERE old_id = c.link_id),
|
||||
c.user_agent,
|
||||
c.browser,
|
||||
c.os,
|
||||
c.referer,
|
||||
c.country,
|
||||
c.created_at,
|
||||
c.updated_at
|
||||
FROM clicks c;
|
||||
|
||||
-- 4. Drop old tables and rename new tables
|
||||
DROP TABLE clicks;
|
||||
DROP TABLE links;
|
||||
DROP TABLE users;
|
||||
|
||||
ALTER TABLE clicks_new RENAME TO clicks;
|
||||
ALTER TABLE links_new RENAME TO links;
|
||||
ALTER TABLE users_new RENAME TO users;
|
||||
|
||||
-- 5. Drop unused indexes
|
||||
DROP INDEX IF EXISTS index_users_api_key;
|
||||
DROP INDEX IF EXISTS idx_links_slug;
|
||||
DROP INDEX IF EXISTS idx_links_slug_optimized;
|
||||
|
||||
-- +micrate Down
|
||||
-- SQL section 'Down' is executed when this migration is rolled back
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
-- Create 10 users
|
||||
INSERT INTO users (name, api_key)
|
||||
VALUES
|
||||
('User 1', 'secure_api_key_1'),
|
||||
('User 2', 'secure_api_key_2'),
|
||||
('User 3', 'secure_api_key_3'),
|
||||
('User 4', 'secure_api_key_4'),
|
||||
('User 5', 'secure_api_key_5'),
|
||||
('User 6', 'secure_api_key_6'),
|
||||
('User 7', 'secure_api_key_7'),
|
||||
('User 8', 'secure_api_key_8'),
|
||||
('User 9', 'secure_api_key_9'),
|
||||
('User 10', 'secure_api_key_10');
|
||||
|
||||
-- Create 1,000 links (100 per user)
|
||||
WITH RECURSIVE link_numbers(n) AS (
|
||||
SELECT 1
|
||||
UNION ALL
|
||||
SELECT n+1 FROM link_numbers
|
||||
LIMIT 1000
|
||||
)
|
||||
INSERT INTO links (user_id, slug, url)
|
||||
SELECT
|
||||
((n-1) % 10) + 1, -- User ID (1-10)
|
||||
'slug' || n, -- Unique slug
|
||||
'https://sjdonado.com/page/' || n
|
||||
FROM link_numbers;
|
||||
|
||||
-- Create 1,000,000 clicks (1,000 per link)
|
||||
WITH RECURSIVE link_numbers(link_id) AS (
|
||||
SELECT id FROM links
|
||||
),
|
||||
click_batch(link_id, n) AS (
|
||||
SELECT link_id, 1 FROM link_numbers
|
||||
UNION ALL
|
||||
SELECT link_id, n+1 FROM click_batch WHERE n < 1000
|
||||
)
|
||||
INSERT INTO clicks (link_id, user_agent, browser, os, referer, country)
|
||||
SELECT
|
||||
link_id,
|
||||
CASE (n % 5)
|
||||
WHEN 0 THEN 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'
|
||||
WHEN 1 THEN 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15)'
|
||||
WHEN 2 THEN 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0)'
|
||||
WHEN 3 THEN 'Mozilla/5.0 (X11; Linux x86_64)'
|
||||
ELSE 'Mozilla/5.0 (Android 11; Mobile)'
|
||||
END,
|
||||
CASE (n % 3)
|
||||
WHEN 0 THEN 'Chrome'
|
||||
WHEN 1 THEN 'Firefox'
|
||||
ELSE 'Safari'
|
||||
END,
|
||||
CASE (n % 4)
|
||||
WHEN 0 THEN 'Windows'
|
||||
WHEN 1 THEN 'macOS'
|
||||
WHEN 2 THEN 'iOS'
|
||||
ELSE 'Android'
|
||||
END,
|
||||
CASE (n % 6)
|
||||
WHEN 0 THEN 'https://sjdonado.com'
|
||||
WHEN 1 THEN 'https://donado.co'
|
||||
WHEN 2 THEN 'https://idonthavespotify.donado.co'
|
||||
WHEN 3 THEN 'https://spookyplanning.com'
|
||||
WHEN 4 THEN 'https://github.com/sjdonado'
|
||||
ELSE NULL
|
||||
END,
|
||||
CASE (n % 10)
|
||||
WHEN 0 THEN 'US'
|
||||
WHEN 1 THEN 'UK'
|
||||
WHEN 2 THEN 'Canada'
|
||||
WHEN 3 THEN 'Germany'
|
||||
WHEN 4 THEN 'France'
|
||||
WHEN 5 THEN 'Japan'
|
||||
WHEN 6 THEN 'Australia'
|
||||
WHEN 7 THEN 'Brazil'
|
||||
WHEN 8 THEN 'India'
|
||||
ELSE 'China'
|
||||
END
|
||||
FROM click_batch;
|
||||
Reference in New Issue
Block a user