今日已更新 344 条资讯 | 累计 37249 条内容
关于我们

标签:#sql

找到 143 篇相关文章

AI 资讯

Mastering Hive in Flutter: A Step by Step Beginner's Guide to Fast Local Storage

Introduction When building a Flutter application, you'll often need to store data on the user's device. For example: Saving user preferences Storing login information Caching API responses Creating offline applications Building note-taking or to-do apps While there are several local storage solutions available, Hive is one of the fastest and easiest local storage for Flutter developers. In this tutorial, you'll learn Hive from scratch by building a simple example. No prior database knowledge is required. What is Hive? Hive is a lightweight, NoSQL database written entirely in Dart. It stores data directly on the device, making it perfect for Flutter applications. Why use Hive? Extremely fast Works offline No native platform code required Simple API Easy to learn Great for small and medium-sized applications Think of Hive as a collection of boxes where each box stores your application's data. Hive ├── User Box ├── Settings Box ├── Notes Box └── Products Box Each Box is similar to a table in traditional databases. Step 1: Create a Flutter Project Create a new Flutter project. flutter create hive_demo Open the project. cd hive_demo Step 2: Install Hive Open pubspec.yaml and add the following packages. dependencies : flutter : sdk : flutter hive : ^2.2.3 hive_flutter : ^1.1.0 Then install them. flutter pub get Step 3: Initialize Hive Before using Hive, initialize it inside main() . import 'package:flutter/material.dart' ; import 'package:hive_flutter/hive_flutter.dart' ; void main () async { WidgetsFlutterBinding . ensureInitialized (); await Hive . initFlutter (); await Hive . openBox ( 'settings' ); runApp ( const MyApp ()); } Here we open a box called settings . Step 4: Understanding Boxes A Box is where Hive stores data. Imagine this box: Settings Box theme -> dark username -> Alex loggedIn -> true Keys are on the left. Values are on the right. Step 5: Save Data Saving data is incredibly simple. var box = Hive . box ( 'settings' ); box . put ( 'username' , 'John' );

2026-07-30 原文 →
开发者

AWS retired its free database migration assessment tool. The reason should change how you build developer tools.

On May 20, 2026, AWS ended support for DMS Fleet Advisor. Fleet Advisor answered a question every migration team asks first: what is actually in my database estate, and how hard will it be to move? It was free. It was fully managed. It was backed by the largest cloud provider on earth. It still lost. AWS's official notice says only: "After careful consideration, we decided to end support for AWS DMS Fleet Advisor." No reason given. But you don't need one — the documentation tells you. Here is what Fleet Advisor required before it would tell you a single thing about your databases: Install a standalone data collector in your local environment Create an Amazon S3 bucket Create IAM policies, roles, and users — via CloudFormation, which was the recommended path Create database users with the minimum required permissions on every source Establish network access from the collector to each database server Then you'd meet the ceilings: recommendations for up to 100 databases at a time, one-to-one target mapping only, no multitenant server support. Now picture running that gauntlet inside a bank. You are a Business Solution Architect. You have been asked to scope a migration. You do not yet have approval for the migration — that approval is what the assessment is for . And to produce the assessment, you must first request production database credentials, get an agent binary through software approval, provision an S3 bucket, and get an IAM stack past a security review. That is a six-week procurement conversation to answer a question you were hoping to answer this week. AWS's replacement recommendation is Migration Evaluator — a consulting-led engagement. Read that as the finding it is: AWS looked at self-serve migration assessment, and concluded that humans and services do it better than a product. I think they were half right. And the half they got wrong is the interesting part. The lesson: friction is a competitor, and it usually wins We talk about developer tools as if the

2026-07-30 原文 →
AI 资讯

Optimizing an 18 TB Azure SQL Hyperscale Database — Part 1: Context & Principles

Before we start This is a series about the intermediate results of an ongoing effort, not a finished story. It isn't an academic paper — it's a record of real engineering work and the insights that emerged along the way. Also, it's not about AI generating code. The AI angle here is about investigation and research — a careful, governed use of AI as a tool, not an autopilot — something I'll come back to in the final part. A word on why now, with the project still unfinished: details fade — the small technical decisions, the intermediate observations, the context in which a given call was made. Writing this down while the work is still ongoing is partly how I keep that context from slipping away. And that context matters: it's a reminder that every past decision, mine or anyone else's, was made for reasons that made sense at the time. One more note: none of this happened instead of product work. All of it ran alongside building new features and fixing bugs — the roadmap never paused for it. On confidentiality: I don't name the Customer, and I avoid any personal data or details a competitor could use. For the same reason, I don't mention anyone by name and refer to colleagues only by role. I won't name them, but I want to acknowledge up front that much of what follows was only possible thanks to the people I work with. The numbers are approximate and rounded — the point is the order of magnitude and the reasoning, not the exact figure. And a framing to carry through the series: at this scale, optimization is less a sprint than a marathon — yes, probably the most overused metaphor around, but here it genuinely fits: steady pacing beats sprinting, and you get there one careful step at a time. How I ended up here I'm a software engineer, and I've spent most of my career close to backends and databases. I've also led teams as a technical team lead — though over time I've deliberately shifted back toward more hands-on technical roles, which is where I'm most effective and m

2026-07-29 原文 →
AI 资讯

BUILDING GREENWOOD ACADEMY DATABASE USING POSTGRESQL

INTODUCTION Creating Greenwood academy database is essential for managing the students, subject and exam results efficiently. PostgreSQL, a powerful open-source relational database system, offers the perfect foundation for such a project. The main areas areas in SQL covered in this projects are : 1. DDL (Data Definition Language) DDL commands define, modify, and change the physical structure of database objects like tables and schemas. The first step is to create a greenwood academy schema using the create command. create schema greenwood_academy ; set search_path to greenwood_academy ; Next is to crete tables in the schema; The schema has 3 tables students,subject and exam results. create table greenwood_academy . students ( student_id INT PRIMARY key , first_name VARCHAR ( 50 ) NOT null , last_name VARCHAR ( 50 ) NOT null , gender VARCHAR ( 1 ), date_of_birth DATE , class VARCHAR ( 10 ), city VARCHAR ( 50 ) ); create table greenwood_academy . subject ( subject_id INT PRIMARY key , subject_name VARCHAR ( 100 ) NOT null unique , department VARCHAR ( 50 ), teacher_name VARCHAR ( 100 ), credits INT ); create table greenwood_academy . exam_results ( result_id INT PRIMARY key , student_id INT NOT null , subject_id INT NOT null , marks INT NOT null , exam_date DATE , grade VARCHAR ( 2 ) ); ALTER - This command changes the structure of tables in a database. Core Actions You Can Perform Add columns : Insert a new column and its data type into a table. The school realised that the nthey forgot to add phone numbers in the students table. The following command is used to add the data alter table greenwood_academy . students add column phone_number VARCHAR ( 20 ); Rename colums : Change the name of a table or a column. The column credit has to be changed to credit hours alter table greenwood_academy . subject rename column credits to credit_hours ; Drop columns : Delete an unwanted column from a table. Later the school relised that the phone number column is nolonger needed. a

2026-07-28 原文 →
AI 资讯

WHERE $1::timestamptz IS NULL OR "timestamp" > $1

SQL is quite flexible, making it easy to write a single query that works for two situations: one without a parameter and a WHERE clause, and another with a parameter for filtering, all in the same SQL query. For example, I came across a benchmark comparing MongoDB and PostgreSQL that shows how to handle pagination effectively—by avoiding OFFSET and instead using the last value to fetch the next set of results. The first page includes a WHERE clause along with ORDER BY and LIMIT, while the following pages add an extra WHERE condition. In the MongoDB version of this benchmark, the filter is handled within the application, which leads to two separate queries for these scenarios. export async function getOrders ( cursor ) { const match = cursor ? { timestamp : { $gt : new Date ( cursor ) } } : {}; const rows = await orders . aggregate ([ { $match : match }, { $sort : { timestamp : 1 } }, { $limit : PAGE_SIZE }, ]) We can do the same in PostgreSQL using a single prepared statement. SQL is such a powerful language that it often feels tempting to write it this way: SELECT * FROM orders WHERE $ 1 :: timestamptz IS NULL OR "timestamp" > $ 1 ORDER BY "timestamp" ASC LIMIT $ { PAGE_SIZE } If $1 is NULL, it skips the second condition in the OR clause and retrieves all rows without filters, resulting in a broad fetch. When $1 has a value, it filters the results using that specific value, enabling a more targeted search. However, using a generic query can sometimes lead to a less-than-ideal execution plan that's not perfectly tailored for each specific situation. I gave it a try: drop table if exists orders ; create table orders ( order_id text primary key , "timestamp" timestamptz not null ); create index idx_orders_timestamp on orders ( "timestamp" ); insert into orders select 'ORD-' || g , '2025-01-01' :: timestamptz + g * interval '1 minute' from generate_series ( 1 , 5000000 ) as g ; analyze orders ; prepare getorders ( timestamptz , int ) as select * from orders where $ 1 :

2026-07-27 原文 →
AI 资讯

Following ROWIDs Through an Oracle Unique Index Update

I've always been amazed by how Oracle Database handles updates to a unique column—performing set-based operations that don't violate the unique constraint, yet when executed row by row, it temporarily permits duplicates. SQL > create table franck ( val int unique ); Table created . SQL > insert into franck values ( - 1 ) , ( 1 ) ; 2 rows created . SQL > select val from franck ; VAL ---------- - 1 1 SQL > update franck set val =- val ; 2 rows updated . SQL > select val from franck ; VAL ---------- 1 - 1 From a SQL perspective, this is expected behavior, but not all databases support it without raising an error: Db2 , SQL Server , and Oracle handle it without error. PostgreSQL raises ERROR: duplicate key value violates unique constraint "franck_val_key", DETAIL: Key (val)=(1) already exists. This works with a deferred constraint. MySQL or MariaDB raise Duplicate entry '1' for key 'franck.val' SQLite raises { "code": "SQLITE_CONSTRAINT_UNIQUE" } MongoDB raises E11000 duplicate key error collection: test.franck index: val_1 dup key: { val: 1 } db . franck . createIndex ({ val : 1 }, { unique : true }); db . franck . insertMany ([ { val : - 1 }, { val : 1 } ]); db . franck . updateMany ({},[ { $set : { val : { $multiply :[ " $val " , - 1 ]} } } ]); MongoServerError : Plan executor error during update :: caused by :: E11000 duplicate key error collection : test . franck index : val_1 dup key : { val : 1 } This is surprising because Oracle unique indexes store the indexed columns as the B-tree key and the ROWID as the associated data. Non-unique indexes add the ROWID to the physical key and are required for a deferrable unique constraint to allow temporary duplication before the end of the transaction. So how do non-deferrable unique indexes allow duplication during a single update statement? In this simple example, I would expect: The initial index entries are: (-1): row #1 and (1): row #2 Updating the first row deletes the first entry (-1): row #1 and adds one with (1):

2026-07-27 原文 →
AI 资讯

Why I Built a Free SSMS Extension to Stop Destructive Queries

The moment that started it A colleague of mine was cleaning up some old records in a staging environment. Same query he'd run a dozen times before, except this time he was connected to production. He hit F5. No WHERE clause. 47,000 rows gone in milliseconds . We recovered from a backup, lost about two hours, and nobody got fired. But it stuck with me:** SSMS will let you delete an entire production table with the same amount of friction as running a SELECT 1**. No pause, no confirmation, nothing. The tool that DBAs and backend developers spend all day in has zero built-in protection against the single most common way people destroy data. So I built one. What SQL Guard does SQL Guard is a free SSMS extension (18 through 22) that inspects your query the moment you press F5, and pauses execution if it matches a known destructive pattern: DELETE without WHERE UPDATE without WHERE TRUNCATE TABLE DROP TABLE / DROP DATABASE / DROP PROCEDURE ALTER DATABASE Dangerous EXEC calls MERGE without a filter When one of these fires, you get a dialog showing exactly what object would be affected, with three options: cancel, run anyway, or run and ignore for the rest of the session. The point isn't to block you — it's to make the action conscious. Most accidental damage happens because muscle memory took over, not because someone genuinely meant to wipe a table. How the detection works Nothing exotic here, and honestly that's by design. SQL Guard runs a lightweight pattern-matching pass over the query text before it hits the connection. No parsing tree, no round-trip to the server, no measurable latency — it runs in under a millisecond, so you never notice it on normal queries. The core idea is simple: certain statements are only safe when scoped by a WHERE clause, and the extension checks for that clause's absence rather than trying to understand the full semantics of the query. That keeps false positives low and means it works the same way whether you're on SQL Server 2016 or the la

2026-07-26 原文 →
AI 资讯

Como crear Roles de Usuarios RBAC Plano PHP MySQL

Guía crear Roles de Usuario usando RBAC Plano con PHP MySQL Agustin RamosJul 24, 2026PHP Stuffs El control de acceso basado en roles (RBAC) es utilizado en la mayoría de los sistemas para definir qué puede hacer cada usuario. En su versión más simple, conocida como RBAC plano, no es necesaria una tabla de permisos: cada usuario tiene un único rol, representado por un número, y ese número es el que determina qué se le permite hacer dentro del sistema. En esta guía es construido un módulo de RBAC plano completo, con base de datos, conexión, lógica de validación y ejemplos de uso, usando solo PHP y MySQL. Si necesitas repasar los fundamentos antes de continuar, puedes consultar nuestra guía de PHP y MySQL. Qué es el RBAC plano En este modelo, cada rol es representado por un ID numérico. La regla que se sigue en esta guía es simple: entre más bajo el número, mayor es el nivel de acceso. 1 = admin (mayor nivel de acceso) 2 = subadmin 3 = encargado 4 = empleado (menor nivel de acceso) Con esta lógica, validar “solo administradores o superiores” se reduce a una simple comparación: role_id <= 2. Base de datos Son necesarias únicamente dos tablas: rol y user. La columna role_id, dentro de user, es la que define el nivel de acceso de cada persona. Todo este bloque está guardado en el archivo schema.sql. Cómo ejecutarlo: copia todo el bloque de código y pégalo directamente en tu consola de MySQL (o en phpMyAdmin / MySQL Workbench). Esto crea la base de datos rbac_plano, sus tablas y los datos de ejemplo automáticamente. -- schema.sql CREATE DATABASE rbac_plano; USE rbac_plano; -- Tabla rol. -- El ID es usado como nivel: entre más bajo, más privilegios. CREATE TABLE rol ( id TINYINT UNSIGNED PRIMARY KEY, name VARCHAR(50) NOT NULL UNIQUE ); -- Se insertan los 4 roles base del sistema. INSERT INTO rol (id, name) VALUES (1, 'admin'), (2, 'subadmin'), (3, 'encargado'), (4, 'empleado'); -- Tabla user. -- Cada usuario tiene un único role_id (no hay tabla de permisos). CREATE TABLE us

2026-07-25 原文 →
AI 资讯

Architecting RoutePe Auto: Building a Scalable Transport Management Software with Laravel, React, Flutter and MySQL

Modern logistics is built on time-sensitive operations, yet traditional freight procurement suffers from friction. Legacy systems depend heavily on fragmented offline negotiations, opaque spot market prices, manual Lorry Receipt (LR) tracking, and coordination gaps between warehouse controllers and field drivers.To eliminate these operational bottlenecks, RoutePe Auto was engineered as a high-throughput Transport Management Software . The platform unites real-time spot bidding, pay-per-tender corporate procurement, vehicle discovery, automated freight billing, and live multi-point tracking into a unified ecosystem. Here is an architectural breakdown of how RoutePe Auto was designed using Laravel on the backend, React on the web frontend, a native Mobile App , and MySQL for transactional integrity. Architecture Overview ┌──────────────────────────┐ │ React Web Dashboard │ │ (Shippers / Logistics) │ └────────────┬─────────────┘ │ REST / WebSockets │ ┌──────────────────┐ ┌────────────▼─────────────┐ ┌──────────────────┐ │ Mobile App │◄────►│ Laravel API Gateway │◄────►│ MySQL Database │ │(Drivers/Fleet) │ │ & Execution Core │ │ (ACID Transactions) └──────────────────┘ └────────────┬─────────────┘ └──────────────────┘ │ ┌──────▼──────┐ │ Redis Queue │ └─────────────┘ The system operates across three tiers:The Web App Layer: Built with React, offering enterprise shippers a dynamic workspace to broadcast loads, review bids, manage tenders, and monitor active routes. The Field Execution Layer: A dedicated Mobile App for drivers and fleet operators, streaming real-time location updates, uploading electronic Proof of Delivery (ePOD) signatures, and receiving job dispatches. The Core Engine: A robust Laravel REST API backend handling business logic, asynchronous task dispatching, document generation, and balance ledger management against a relational MySQL store.Database Design in MySQLA core requirement for any Transport Management Software is strict transactional integrity.

2026-07-25 原文 →
AI 资讯

Deploying Rails 8 on Render Free Tier: Bypassing the 512MB RAM and Read-Only Storage Limits

1. Introduction Hello from Japan! 🇯🇵 I am an active truck driver in Japan self-studying Python, leveraging my logistics domain knowledge to become a Web Engineer. (English is my second language, but I'm excited to share my journey with developers around the world!) I started my self-study journey on May 12, 2026. In this article, I summarize the process of deploying Ruby on Rails 8 to a PaaS (Render Free Tier) and how I tackled the strict resource constraints I ran into. Check out my GitHub here👈️ (Note: Most repository documentation and commits are currently in Japanese.) 2. Environment Development : Lenovo G580 (Lubuntu 24.04 LTS / 16GB RAM / Upgraded SSD) Production : Render (Free Tier: 512MB RAM) Testing Device : Xiaomi 15T 3. Challenges & Solutions ① Git Repository Structure Inconsistency Issue : An unnecessary .git directory existed inside a subdirectory, causing errors during deployment. Solution : Deleted the nested .git directory to restore repository hierarchy integrity. ② Build Failure via Render Free Tier RAM Limit (512MB) Issue : Executing asset compilation on Render triggered Out-Of-Memory (OOM) crashes, forcibly killing the build process. Solution : Precompiled assets locally and committed the static files to the repository, significantly reducing memory usage on the production build server. ③ SQLite3 Write Permission Error Issue : Encountered database write permission errors during CRUD operations in production. Render's file system is read-only by default, except for designated directories (such as storage/ ). Solution : Updated config/database.yml to direct the SQLite3 database file to a path with write permissions (e.g., under storage/ ). 4. Conclusion By applying these workarounds, I successfully verified the deployment and operation of a Rails 8 application on Render's Free Tier. (Please note: Although production runtime works properly, because the setup prioritizes local configurations, some automated CI tests on GitHub currently report errors.

2026-07-25 原文 →
AI 资讯

Inside LioranDB's Full-Text Search Segments

A normal secondary index can answer: status = "active" It cannot efficiently answer: documents containing "distributed database" LioranDB therefore has a dedicated text-segment architecture. Tokenization Text is split on non-alphanumeric characters. Depending on index options, tokens can be normalized to lowercase and filtered through stopwords. "Building Distributed Databases" becomes ["building", "distributed", "databases"] Segment contents A LioranDB text segment can contain several files and structures: Term dictionary Posting lists Document map Document-length norms Optional term positions Bloom filter Segment metadata A posting connects a term to the local documents containing it. "database" → [doc 2, doc 8, doc 19] Positions can record where the term appears inside each document. That enables more advanced query behaviour and phrase-aware features. Global and local document IDs Each segment assigns compact local IDs to its documents. A separate document map translates them back to global document IDs. This keeps postings smaller while preserving the external identity of the record. Bloom filters Each segment also maintains a Bloom filter for terms. Before reading a segment's postings, the query path can test whether the term might exist there. A negative answer is definitive. A positive answer means the segment may contain the term and should be checked. Query modes The text query layer supports modes such as: AND OR It also emits scored documents and metrics including: Query time Postings read Candidate documents Segments searched Full-text search is essentially a specialized database living beside the document database. Its data structures, compaction behaviour, scoring, and caching needs are different enough that treating it as a plain secondary index would be a mistake. Built by Swaraj Puppalwar under Lioran Group . Learn more: LioranDB Lioran Developer Solutions Lioran Group

2026-07-25 原文 →
AI 资讯

Memtables: The Fast Write Buffer Inside LioranDB

Disk structures are durable, but updating them for every write is expensive. LioranDB uses memtables to absorb writes before flushing them to the on-disk B+ tree. What is a memtable? A memtable is an ordered in-memory map. In LioranDB, each entry contains either: Value ( bytes ) or: Tombstone A tombstone represents a deletion. The memtable also tracks: Approximate memory usage Minimum LSN Maximum LSN Entry count Put count Delete count The write path A simplified write path looks like this: Application write ↓ WAL durability ↓ Mutable memtable ↓ Immutable memtable queue ↓ Background flush ↓ Disk B+ tree The active mutable memtable accepts new writes. When it crosses a size limit, the engine rotates it into an immutable memtable. That immutable table is no longer modified and can safely be flushed in the background. Why ordered maps? LioranDB uses an ordered map for memtable entries. This helps because the flush process can emit keys in sorted order, which is friendly to the B+ tree and bulk-write paths. It also simplifies range merging between: Mutable data Immutable data On-disk pages Backpressure Background flushing cannot be allowed to fall behind forever. LioranDB therefore tracks limits such as: Maximum immutable memtables Maximum immutable bytes Partition-wide queue limits Maximum writer stall duration If the disk cannot drain the backlog quickly enough, the foreground write path slows down. That may sound undesirable, but controlled backpressure is much safer than consuming memory until the process dies. A memtable is not merely a cache. It is a pressure valve between CPU-speed writes and disk-speed persistence. Without that valve, the engine would either become slow on every commit or dangerously accumulate unbounded work. Built by Swaraj Puppalwar under Lioran Group . Links: LioranDB Lioran Developer Solutions Lioran Group

2026-07-25 原文 →
AI 资讯

Inside LioranDB: Why the Storage Engine Speaks Bytes, Not JSON

Most developers think of LioranDB as a document database. Internally, however, its storage engine does not understand documents, objects, fields, or JSON. It understands only: table + key bytes + value bytes That separation is intentional. The architecture LioranDB is split into two major layers: Application ↓ Document DBMS ↓ Transactional key-value engine ↓ WAL, memtables, B+ tree, pager and disk The engine exposes operations such as: get ( table , key ) put ( table , key , value ) delete ( table , key ) scan ( table , range ) The DBMS layer then adds document-oriented features: Collections JSON encoding Queries Updates Secondary indexes Text indexes Transactions For example, a secondary index can be represented as: idx:status:active → document_id A text index can be represented as: inv:database → posting_list The storage engine does not need to know what status , active , or database means. It only stores ordered bytes. Why this matters This architecture keeps the core engine small and reusable. The engine focuses on difficult low-level concerns: Durability Page management Transactions Recovery Ordering Concurrency Range scans The DBMS focuses on application-level semantics. This also makes it possible to build different data models over the same engine in the future. A document database is therefore not one giant component. It is a collection of carefully separated layers. That separation is one of the most important architectural decisions inside LioranDB. LioranDB is being developed by Swaraj Puppalwar under Lioran Group . Learn more: LioranDB Lioran Developer Solutions Lioran Group

2026-07-25 原文 →
AI 资讯

B+tree height after delete: PostgreSQL fast root

Many databases use B+tree indexes, but they all differ. It's a sorted structure. The leaf pages are logically sorted so that a specific key value belongs to one page. A lookup by value reaches a single leaf page and either directly finds an entry for that value or immediately knows there's no entry with that key. When a page becomes full, it is split into two pages, each covering its own dedicated range. To find the right page, an internal page holds the range of values for the pages below. This internal page can become full, and a new level is added above it. Finally, at the highest level, there's a single internal page that is the root. A lookup always starts at the root and goes down to the leaves, following the branches of internal pages. In a traditional B+tree lookup, the cost is proportional to the height of the tree because the search starts at the root and descends to a leaf: 1 page to read when all fits in one leaf that is also the root (0 levels of internal pages, total height is 1). With small keys, this level can typically index hundreds of rows. 2 pages to read when there's one root that can list all leaf pages (1 level of internal page, total height is 2). With small keys, this level can typically index tens or hundreds of thousands of rows. 3 pages to read when there's one level of branches under the root (so 2 levels of internal pages, total height is 3). With small keys, this level can typically index millions of rows. This means that finding one key within ten million rows may require traversing 3 index pages, where most of them are probably in cache given the small number of branches compared to the leaves. For a given index size, whatever the value you are looking for, it's always the same number of pages to read because the index is balanced (the commonly accepted meaning of the B in B+tree). This property is maintained because any page can split, but only splitting the root adds another level. I've described how the height of an index can incr

2026-07-24 原文 →
AI 资讯

NocoBase and the mystery of the shifted timestamps: MySQL vs PostgreSQL, measured

There's a class of bug reports that keeps coming back in the NocoBase community, especially in the Chinese-language forum: "all my times are off by 8 hours" or "dates show up as the day before." China is UTC+8, so the shift is 8 hours there. I run my instances at UTC+9, and sure enough — my shift is 9 hours. Whatever your offset is, that's the size of your shift. That pattern is a strong hint that this isn't random corruption. It's a mechanism. I set up NocoBase 2.x against both PostgreSQL and MySQL and measured what actually gets stored and how it gets reinterpreted, until the mystery had a concrete answer. Test setup: NocoBase 2.0.51 and 2.1.23 (official Docker images) × PostgreSQL 16 and MySQL 8.4. All data written and read through the REST API, with the server timezone controlled via the container's TZ environment variable. I'm deliberately ignoring the browser-side rendering here — this is about what the server stores and how it interprets it. Background: 2.x has four datetime field types NocoBase 2.x collections offer four datetime-ish field types ( official list — though several of the per-type detail pages still say "To be added", which is exactly why I measured instead): Type What it's for Datetime (with time zone) Absolute instants — event start times, logs Datetime (without time zone) Wall-clock times you want preserved as-is Date only Birthdays, due dates, anniversaries Unix timestamp System integration Measurement 1: what each type actually stores I imported "2026-07-12 09:00" via xlsx and looked at the raw values in each database (identical on 2.0.51 and 2.1.23): Field type PostgreSQL MySQL Datetime (with TZ) timestamptz → 2026-07-12 09:00:00+09 ( an absolute instant, offset included ) DATETIME → 2026-07-12 09:00:00 ( wall clock only — no offset information ) Datetime (without TZ) timestamp → 09:00:00 DATETIME → 09:00:00 Date only date → 2026-07-12 date → 2026-07-12 The first row is the whole story. The same field type — "Datetime (with time zone)" — i

2026-07-23 原文 →
AI 资讯

Catch the dangerous Postgres migration at the CI step

-- looks routine in review, locks your table in production: CREATE INDEX idx_orders_customer ON orders ( customer_id ); ALTER TABLE users ALTER COLUMN email SET NOT NULL ; Both of those statements hold a lock that blocks traffic while they scan or build against the table. On a small table you never notice. On a busy production table it is downtime, and a diff review does not catch it because the SQL looks fine. pg-migration-guard is a free tool that reads the migration and flags these before they reach production: $ pg-migration-guard V42__orders.sql WARN IDX01 CREATE INDEX without CONCURRENTLY [becomes a blocker on a large or busy table] Why: Plain CREATE INDEX takes a lock that blocks all writes until the build finishes. Safe: CREATE INDEX CONCURRENTLY idx ON tbl (col); -- outside a transaction WARN NN01 SET NOT NULL scans the whole table under ACCESS EXCLUSIVE Safe: ADD CONSTRAINT c CHECK (col IS NOT NULL) NOT VALID; VALIDATE CONSTRAINT c; then SET NOT NULL; Summary: 0 blocker, 2 warn, 0 advisory Why migrations bite Whether a Postgres migration is safe has almost nothing to do with intent and everything to do with locks. A migration is dangerous when it holds a strong lock while it scans or rewrites a large table. ACCESS EXCLUSIVE blocks reads and writes; SHARE blocks writes. The change that reads fine in review is the one that quietly takes that lock. Put it in CI The most useful place for this is the pull request, so a risky migration fails the build before anyone merges it. There is a GitHub Action: name : migration-guard on : pull_request : paths : [ " db/migration/**.sql" ] jobs : guard : runs-on : ubuntu-latest steps : - uses : actions/checkout@v4 - uses : actions/setup-python@v5 with : python-version : " 3.x" - uses : technical-turtle/pg-migration-guard@v1 with : path : db/migration fail-on : blocker Each finding shows up as an inline annotation on the diff, so the author sees exactly which line is the problem and what the safe rewrite is. Or run it locall

2026-07-22 原文 →
AI 资讯

Resume Optimization for US Data Engineering from WeChat Mini-Programs

Why Your WeChat Mini-Program Work Is Actually Relevant US data engineering interviews prioritize hands-on experience with data pipelines, SQL, and scalable storage. WeChat mini-programs, though often seen as front-end tools, generate and process substantial backend data. If you designed the logic behind user actions, session management, or real-time updates, you already have transferable skills. The key is to stop describing the mini-program as a "feature" and start describing it as a "data system." Recruiters don't care about WeChat's UI components; they care about how you moved, transformed, and stored data. The Core Translation: From Mini-Program to Data Engineering When rewriting your resume, map each mini-program task to a standard data engineering function: User interaction logic → Event-driven data pipeline (e.g., Kafka, AWS Kinesis, or custom queues) WeChat cloud functions → Serverless compute (e.g., AWS Lambda, Azure Functions) Database reads/writes via WeChat API → NoSQL or relational database operations (e.g., MongoDB, MySQL, DynamoDB) Session tracking or analytics → ETL pipeline extracting user behavior data into a warehouse Do not use WeChat-specific terms like "wx.request" or "Mini Program SDK" without explaining the data they handled. Replace them with equivalent English terms. A Quick Side-by-Side Translation Table WeChat Term US Data Engineering Equivalent WeChat Cloud Database Managed NoSQL database (like MongoDB Atlas) Mini Program Backend with Cloud Functions Serverless data processing (AWS Lambda) User login & session management Authentication pipeline with token storage Real-time message push Event-driven notification system Reshaping Your Bullet Points: Before and After Generic bullet points kill your chances. Here is a concrete rewrite that turns a typical WeChat mini-program description into a data engineering achievement. Before (Chinese-English hybrid, vague): "Developed a WeChat mini-program for e-commerce with 50k users. Used wx.request

2026-07-20 原文 →
AI 资讯

Reproduce SQLite WAL Checkpoint Starvation With One Forgotten Reader

A SQLite service can keep answering health checks while its WAL grows without a successful checkpoint. One forgotten read transaction is enough to reproduce the risk. Run a controlled drill: Enable WAL mode and create a small table. Open connection A, begin a read transaction, and keep it open. From connection B, commit batches of writes for 60 seconds. Sample WAL bytes and checkpoint results every second. Release A and observe recovery. PRAGMA journal_mode = WAL ; PRAGMA wal_checkpoint ( PASSIVE ); Record the three checkpoint counters plus duration, WAL file size, oldest transaction age, write latency, and free disk bytes. A green SELECT 1 says nothing about checkpoint progress. My fault-injection gate looks like this: Given: one reader holds its transaction When: 10,000 writes commit Then: writes remain bounded And: WAL growth triggers an alert before the disk budget When: the reader closes Then: checkpoint progress resumes and WAL size converges Do not start with an automatic TRUNCATE loop. A busy result is evidence of contention; aggressive checkpoints can add latency without fixing the reader lifecycle. First identify long transactions, ensure result iterators close, and define a maximum transaction age. SQLite’s WAL documentation explains that a checkpoint must stop when it reaches pages beyond an active reader’s end mark. This is why the drill needs concurrency rather than a synthetic file-growth assertion. Operational thresholds should be tied to a disk budget: alert when projected WAL growth reaches the remaining safe window, not at an arbitrary file size. The runbook should name how to find the oldest reader, how to shed writes, and when a restart is safer than waiting. A health check is useful only when it measures the subsystem that is failing.

2026-07-20 原文 →
AI 资讯

Deploying MySQL on RDS and Joining Tables Like It's Production

Rds challenge lab devto post 🗄️🐬 aws #rds #database #tutorial Build Your DB Server and Interact With Your DB INTRO Did a hands-on AWS challenge lab on Amazon RDS. Task: spin up a managed database, connect from a Linux server, and run real SQL — create tables, insert data, join across tables. No hand-holding here, just requirements to figure out myself. Here's the walkthrough. SCENARIO Service: Amazon RDS Role: Cloud/DB Admin Goal: Launch RDS under set constraints, connect via EC2, run SQL (create, insert, select, join) ARCHITECTURE LinuxServer (EC2) sits in the Lab VPC — this is the client RDS instance (Aurora or MySQL) in the same VPC Security group lets LinuxServer talk to RDS Flow: LinuxServer -> MySQL client (port 3306) -> RDS -> tables STEP 1: LAUNCH THE RDS INSTANCE Constraints for this lab: Engine: Aurora (Provisioned) or MySQL — no serverless Template: Dev/Test or Free tier No standby instance (single-AZ only) Instance size: db.t3.micro to db.t3.medium Storage: gp2, up to 100 GB — no Provisioned IOPS Network: Lab VPC Security group must allow LinuxServer access MySQL only: turn off Enhanced Monitoring On-Demand only These limits keep costs in check — Provisioned IOPS and Multi-AZ are the fastest ways to blow up an RDS bill. Noted the master username, password, and endpoint — needed next. STEP 2: CONNECT TO THE LINUX SERVER Downloaded the PEM key, grabbed the LinuxServer address, connected over SSH: chmod 400 labsuser.pem ssh -i labsuser.pem ec2-user@<LinuxServer-address> This box is just the SQL client — it needs network access to RDS, nothing more. STEP 3: INSTALL MYSQL CLIENT AND CONNECT On the LinuxServer: sudo yum install mysql -y Connect using the master credentials from Step 1: mysql -h <rds-endpoint> -u <master-username> -p If it hangs, it's almost always the security group — check port 3306 inbound. STEP 4: CREATE THE RESTART TABLE CREATE DATABASE lab_db ; USE lab_db ; CREATE TABLE RESTART ( StudentID INT , StudentName VARCHAR ( 100 ), RestartCity VA

2026-07-19 原文 →
AI 资讯

What Happens When an Ordinary Girl Decides to Document Her Journey to Becoming a Java Full Stack Developer?

Do you have 2 minutes? Let's find out together. Before you continue, one small note... This first article isn't about Java, SQL, or coding tutorials. Today is simply about introducing myself, sharing why I decided to start this blog, and telling you what you can expect from the journey ahead. The technical content begins from the next article. Now, let me introduce myself. Hello! I'm Kumudhasri. Today isn't my birthday. It's not New Year's Day. I didn't receive a job offer today. There isn't a special milestone to celebrate. In fact, today is just an ordinary Sunday. But then I asked myself, "Why wait for a special day when I can make today special by taking the first step?" I've never believed in waiting for the perfect time to start. There will always be another Monday, another month, or another excuse. For me, the right time isn't tomorrow. "The right time is right now." So, this is where my journey begins. I'm not someone with an extraordinary story, years of experience, impressive achievements, or exceptional skills. I'm simply a recent B.Tech graduate trying to become a Java Full Stack Developer. Like many people starting out, I'm learning one concept at a time, solving problems, building projects, making mistakes, and figuring things out as I go. Some days I'll make progress. Some days I'll feel stuck. And I'm okay with both. Why am I starting this blog? I'm not writing because I'm an expert. I'm writing because I'm a learner. This blog is my way of documenting everything I learn—not just the wins, but also the mistakes, the confusion, and the lessons that come from working through them. I want this blog to keep me accountable. I want a place where I can organize my thoughts, track my progress, and understand how far I've come. Most importantly, I want my future self to look back at these posts and remember what the beginning looked like. What can you expect from this blog? If you decide to follow this journey, here's what you'll find: SQL challenges and what

2026-07-19 原文 →