AI 资讯
SQL Foundations, Start to Finish
By the end of this page you can say, out loud and in your own words, what every core piece of SQL does. What a table and a row really are. The six clauses, and the order they actually run in, which is not the order you type them. NULL , and why it breaks comparisons. Filtering, aggregation, GROUP BY and HAVING . Joins. CASE . Subqueries, CTEs and window functions. Keys and indexes. That list is most of what an analyst job, an interview, and a first real dataset will ask of you. Here is what to actually do with it. Go through once end to end without stopping, just for the shape. Then come back to the retrieval sheet near the bottom, cover the right-hand column, and try to say each answer before you read it. That second pass is where the learning happens, and there is measured evidence for it further down. The short version: SQL is one sentence with six parts, and every part answers a different question about your rows. Learn what each part does and where it runs, and the rest is vocabulary. One idea decides more of your SQL experience than any other, so it gets the picture. You write a query in one order. The database runs it in a different order. Almost every confusing SQL error is that gap. The original carries a diagram here. In words: Two columns of stacked boxes face each other. The left column, headed "you write", lists the clauses in typing order from top to bottom: SELECT, FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT. The right column, headed "it runs", lists the same clauses in execution order: FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY, LIMIT. Curved lines connect each clause on the left to the same clause on the right. Six of the seven lines run roughly straight across. One line, the one belonging to SELECT, is drawn in a strong accent color and sweeps steeply downward from the very top of the left column to the fifth position on the right, showing that SELECT is written first but runs almost last, after grouping has already happened. What this page
AI 资讯
Report or Analysis?
This guide gives you a test that takes ten seconds and tells you whether the thing you just built is a report or an analysis. Then it gives you four moves that turn one into the other. Every move has a worked SQL example and real numbers. The whole method is here. What you actually do: take the number you just produced, and ask what someone would do differently because of it. If the honest answer is nothing, you have a report. Then you run the four moves below, in order, until the answer is a specific action a specific person can take on Monday. The short version. Data analysis is looking at records of things that already happened and finding a pattern that changes what someone does next. If nothing changes, it was not analysis. It was a report. The same starting number, two endings. The test: what would someone do differently? Before you read the answer, look at the last thing you built and try it yourself. Who was going to act on it, and what were they going to do? Take any number you have produced and finish this sentence out loud: "Because of this, someone should do a specific thing ." Both blanks have to fill in with something real. A named person or team, and an action they control. Here is a real one. "Churn was 4.1% in Q3." Who acts, and how? Nobody can act on that. It is a true, correctly calculated, carefully formatted number, and it changes nothing. That is a report, and reports are useful. A dashboard that tells you the servers are up is doing its job. It is just not analysis. Now the same underlying data, worked further. "Monthly-plan accounts that never opened the import tool churn at 9.2%. Ones that did churn at 1.8%. The email introducing that tool goes out on day 14, and most cancellations happen on day 11." Who acts? The lifecycle marketing owner. What do they do? Move the email to day 3. That is analysis, and the only difference is that it ended somewhere a person can stand. The word "analysis" is doing a lot of quiet work in job descriptions, so
AI 资讯
Can You Run Hybrid Search on One Database? Yes! Here's How CrateDB Does It
Search has got more powerful, but also more complicated It used to be that database queries were simple enough. Either you had an index, or you didn't, and either way you had some kind of optimizer (cost or rule) that turned your SQL statement into a viable plan for finding and returning your data. We now live in a world where in addition to the Boolean logic of traditional RDBMS queries, we also have: Geospatial queries Full text search queries, using BM25 . Vector Search And if that weren't enough, we have to consider that instead of a traditional application issuing the query, it might be an MCP server, and most importantly of all, the business need might be for two or more of these searches to happen at the same time, on the same data. For example: "An MCP server that uses a single, combined geospatial + full text query to identify towns in Bavaria with castles mentioned in text descriptions." How does CrateDB help with this? CrateDB is one of the limited number of products that not only supports all of these search types but is also capable of storing arbitrarily large quantities of data. This is important, as if you have to hit multiple different database servers to solve your business question, not only is your environment much more complicated, but you risk getting incorrect answers as your multiple databases may be out of sync. In this two-part example, based on our playable IOT Analytics scenario, we will show two things: Using Geo + Text to search a weather/tourism database Using CrateDB as a '360 view' for your MCP server If you want to follow along with this post, the setup is based on our IoT Analytics scenario. You can also just skip this blog post and jump straight to the scenario. Using Geo + Full text to search a weather/tourism database The table we're going to use is called ' German Regions ': CREATE TABLE IF NOT EXISTS demo . german_regions ( region_name TEXT PRIMARY KEY , geo_coords GEO_SHAPE , tourism_info TEXT INDEX USING FULLTEXT WITH ( anal
AI 资讯
One breakout title = 99.9% of a studio's traffic: what Roblox's own public API shows about "genre template" games
Roblox exposes game and group stats through public, unauthenticated endpoints — no login, no scraping tricks: GET https://games.roblox.com/v1/games?universeIds=<id>,<id>,... GET https://games.roblox.com/v2/groups/<groupId>/games?limit=50 I used them to pull the full public games list for a few independent creator groups that each ship multiple games in the same cheap-to-build "obby" template genre (think: dozens of studios building the same core traversal loop with a different skin). The question was simple: within one studio's own catalog, how concentrated is traffic in the single best title versus everything else they've shipped? The answer is the same shape every time: a small number of throwaway builds with near-zero traffic, and one outlier that accounts for nearly all of the studio's lifetime visits. Not "most games do okay and one does great" — more like one game is the studio, traffic-wise, and the rest are lottery tickets that didn't hit. As a sanity check against numbers that are already public knowledge (no anonymity concern), I ran the same script against Uplift Games' group (id 295182): $ python3 fetch_group_stats.py 295182 Group 295182: 371 published experiment(s) Total lifetime visits across all games: 44,412,921,224 Top title alone: 44,377,094,324 visits (99.9% of the group's total traffic) Visit-count distribution: 0-10K: 355 game(s) 10K-500K: 12 game(s) 500K-5M: 2 game(s) 5M-50M: 1 game(s) > 50M: 1 game ( s ) One title (Adopt Me) is 99.9% of that group's entire lifetime traffic across 371 shipped experiments. Same power-law concentration as the smaller, anonymized groups in the full writeup — just at a much larger scale. Why this is more than a curiosity : if you're building in a genre like this, the template itself is clearly not the moat — everyone in it ships near-identical mechanics. The variance between a 45-visit build and a 700M-visit build using the same template looks like it's mostly about timing and whatever the discovery algorithm rewar
AI 资讯
Building JONAM: Using Copernicus Earth Observation Data to Help Restore Lake Victoria's Fisheries
"What if satellite data could help protect the livelihoods of millions who depend on Africa's largest lake?" Last weekend, our team JONAM had the privilege of participating in the Kijani Space Hackathon , where we proudly secured 3rd place while tackling Challenge 2: Sustainable Fisheries & Blue Economy . Rather than building another dashboard, we wanted to solve a real problem affecting millions of people around Lake Victoria : declining fish stocks caused by worsening water quality . The Problem Lake Victoria supports millions of people through fishing, transportation, agriculture, and tourism. However, over the years the lake has experienced: Increasing water pollution Poor water quality Frequent algal blooms Reduced fish breeding habitats Declining fish populations For fishing communities, these are not just environmental issues—they directly affect livelihoods, food security, and local economies. Our question became: Can Earth observation data help communities understand where water conditions are becoming unsuitable for fish before the problem becomes critical? Our Solution: JONAM JONAM is an AI-powered web application that combines satellite-derived environmental data with machine learning to monitor water quality and provide insights into conditions that may contribute to declining fish stocks. Instead of relying solely on manual sampling—which is expensive and only covers small areas—our platform continuously analyses satellite observations covering the entire lake. Why Copernicus? To build JONAM, we integrated the KijaniBox API , which provides access to environmental datasets from the Copernicus Programme . Copernicus is the European Union's Earth observation programme. It uses a constellation of Sentinel satellites together with in-situ observations to monitor Earth's atmosphere, land, and oceans. For our project, we focused specifically on live water telemetry variables available through the KijaniBox platform. 1. Water Temperature Satellites measure th
AI 资讯
Most "big budget" clipping campaigns never pay. Here's how to spot them from one scrape
If you clip short-form video for money, you know Whop Content Rewards: hundreds of live campaigns paying $0.15–$20 per 1,000 views. The discover page lets you sort by budget. That sort is quietly costing you nights of work. Here's the number that changed how I pick campaigns: on the live board right now, 21% of active campaigns have never paid out a single cent. Big banner budget, $0 actually spent. A "$30,000 budget" campaign that has paid nobody in three weeks is not a $30,000 opportunity — it's a landing page. The problem: the board doesn't show you payout speed. You can see budget and budget left , but not how fast the money is actually moving — and that's the only number that separates a campaign that pays from a campaign that poses. The trick: the page already contains everything you need Every campaign card on Whop publishes three things: when it was funded, how much has been spent, and how many creators joined. From one snapshot — no monitoring, no state between runs — you can derive: dailyBurnUsd = budgetSpent / daysSinceFunded → is money moving? estimatedDaysLeft = budgetLeft / dailyBurnUsd → will it still be there? payoutPerCreatorUsd = budgetSpent / creators → what did the average clipper earn? budgetPace = "draining" | "healthy" | "slow" | "stalled" That last field is the shortcut. On today's board of 456 campaigns: pace meaning what to do draining <3 days of budget left skip — gone before your clip gains traction healthy 3–60 days this is where you clip slow 60–180 days fine, but budget may outlive the campaign stalled >180 days at current burn the "big budget" mirage — money posted, almost nobody paid null zero paid out so far unproven; could be brand new, could be dead Real example from today: two campaigns, both showing ~$30K budget. One burns $255/day and has paid the average creator $75 . The other burns $19/day — at that rate its budget lasts four years , which is a polite way of saying nobody is getting paid. On the default board they look ident
AI 资讯
Why Apache Airflow Instead of Cron? A Deep Dive Into How Airflow Actually Schedules Your DAGs
"Why not just use a cron job?" is the first question I get whenever someone sees an Airflow DAG. Fair question. Cron works. It's been around for decades. It's simple. The real answer isn't that cron is bad — it's that cron solves a different problem than Airflow does. Cron is a job scheduler . It runs a command at a fixed time. That's it. It doesn't know whether the command succeeded, whether its dependencies are satisfied, or whether it should even run at all today. It just fires the command and moves on. Airflow is a workflow orchestrator . It doesn't just schedule tasks — it models them as a graph of dependencies, tracks their state, retries failed ones, and gives you a UI to see what ran, what failed, and why. Here's where that difference actually matters. The problem cron can't solve Imagine a simple ETL pipeline: Extract raw data from an API Validate and clean it Load into a warehouse Run a transformation Send a Slack alert if anything fails With cron, you'd write five separate cron entries, one per step, and hope the timing works out. If step 2 fails but step 3 runs anyway, you now have bad data in your warehouse. If step 4 takes twice as long one day, you've silently broken your SLA. Nobody gets notified unless you manually add alerting logic to every script. With Airflow, you model this as a DAG: from airflow import DAG from airflow.operators.python import PythonOperator from datetime import datetime with DAG ( dag_id = " daily_etl " , schedule = " 0 6 * * * " , start_date = datetime ( 2026 , 1 , 1 ), catchup = False , ) as dag : extract = PythonOperator ( task_id = " extract " , python_callable = extract_data ) validate = PythonOperator ( task_id = " validate " , python_callable = validate_data ) load = PythonOperator ( task_id = " load " , python_callable = load_to_warehouse ) transform = PythonOperator ( task_id = " transform " , python_callable = run_transformation ) extract >> validate >> load >> transform Airflow guarantees the order. If validate fail
AI 资讯
Monotonic Stack: The Matrix of Array Problems
The Quest Begins (The "Why") I still remember the first time I faced the “Next Greater Element” interview question. The array looked innocent enough, but every brute‑force attempt felt like I was hammering a nail with a sponge— O(n²) time, nested loops, and a sinking feeling that I was missing something elegant. I spent an hour sketching out the problem on a whiteboard, muttering, “There has to be a way to look ahead without looking back every single time.” That frustration is a rite of passage for many developers. We’re taught to think in terms of scanning left‑to‑right, but some array puzzles scream for a different perspective: we need to remember what we’ve seen in a way that lets us answer questions about the future elements instantly. Enter the monotonic stack—a deceptively simple data structure that turns those scary “look‑ahead” problems into straight‑line walks. The Revelation (The Insight) So what’s the secret sauce? A monotonic stack is just a stack that maintains its elements in strictly increasing or strictly decreasing order. Why does that help? Consider the Next Greater Element problem: for each index i , we want the first element to its right that’s larger than arr[i] . If we walk from left to right and keep a stack of indices whose next greater element we haven’t found yet, the stack will naturally be decreasing in value. Why decreasing? Imagine the stack holds indices [i₁, i₂, …, i_k] where arr[i₁] > arr[i₂] > … > arr[i_k] . When we encounter a new value arr[j] , any element on the stack that is smaller than arr[j] has just found its next greater element—namely arr[j] . We pop those indices, record the answer, and stop when we hit a value that’s not smaller (or the stack empties). Then we push j onto the stack. Because each index is pushed once and popped at most once , the total work is linear: O(n) . No nested loops, no repeated scans—just a single pass with a stack that does the heavy lifting. The same invariant works for other “first bigger/smal
AI 资讯
The Executor-Plus-Gate Pattern: Why Cheap Models Need Stronger Verification
Running LLM jobs over hundreds of items, the obvious shortcut is to collapse execution and verification into one model pass: one call, one output, ship it. It fails at scale, and a scoring system for 146 countries across 11 categories shows exactly why. Each score runs 0 to 100 on a single canonical dataset, the overall rating is the arithmetic mean of those 11, and there are no per-country exceptions. One yardstick, applied identically everywhere. Ask a cheap model to generate all 146 in one pass and you get speed with a hidden cost: drift. One country's "friendliness" score reads high because the model read it as social warmth rather than visa bureaucracy. Another's culture score inflates after the prompt happened to emphasize food over history. None of these are bugs, they're quiet inconsistencies, and at 146 items a 5% drift rate means seven countries silently failing the canonicity requirement while every individual score still looks reasonable. The pattern Step one: a cheap executor runs the mechanical pass. Fixed ruleset, all 146 countries in parallel batches, structured JSON out. No judgment calls, just apply rule X to field Y. Step two: a stronger gate verifies before anything ships. Same scale everywhere? Any statistical outlier? Did a category get reweighted mid-run? This is judgment work, holding many items in view at once, and it's what a single combined pass can't do reliably. A model doing both jobs at once optimizes for the wrong thing: it second-guesses the ruleset mid-run, adds nuance where the spec demanded consistency, and marks cases "exceptional" that shouldn't be. Splitting the two roles is faster and cheaper than one model trying to hold both contexts simultaneously. Where the consistency requirement bites The Country Comparison Tool's best-travel-months field works the same way: a month qualifies if it scores 70 or higher on a fixed weather index built from Open-Meteo data, no editorial override, no "tourists usually go in December anyway."
AI 资讯
AI Could Help Fossil Fuel Companies Create More Emissions
New research finds that by making the fossil fuel industry more productive, AI could help increase carbon emissions by up to nearly 5 percent—vastly outpacing the impact of data centers.
AI 资讯
IBM and Red Hat Expand Lightwell to Strengthen Trust and Governance for AI-Era Open Source
IBM and Red Hat have announced an expansion of Lightwell, introducing new commercial offerings designed to help organizations establish trusted, verifiable software supply chains for the age of AI-assisted software development. By Craig Risi
AI 资讯
Using Machine Learning to Direct Limited HIV Programme Resources to Communities with the Greatest Need
Imagine working as a Data Analyst in a healthcare Non-Governmental Organization (NGO) implementing HIV and AIDS programmes across several communities. The organization has limited resources. There may not be enough funding, healthcare workers, testing kits, transport, outreach teams, or community programmes to serve every community at the same intensity. This creates an important question: How can we use data and machine learning to direct limited programme resources to communities with the greatest need? This is where Machine Learning (ML) can become valuable. Rather than distributing resources equally across all communities, an NGO can use historical programme data to identify communities experiencing greater HIV-related service gaps or higher levels of need. Resources can then be prioritized based on evidence. What Is Machine Learning? Machine Learning is a branch of Artificial Intelligence that enables computers to learn patterns from data and use those patterns to make predictions or support decisions. Instead of manually creating rules for every situation, you provide the algorithm with historical data and allow it to identify relationships within that data. For example, the NGO could have this information about different communities: Community HIV Testing Coverage ART Coverage Missed Appointments Outreach Activities Community A 85% 90% 5% High Community B 52% 61% 25% Low Community C 70% 75% 15% Medium Community D 40% 55% 32% Low Looking at this data, Community D appears to have greater programme gaps than Community A. However, in a real programme, the decision should not be based on one indicator alone. Machine learning can analyse many variables simultaneously to identify communities that may require greater attention. Why Resource Allocation Matters in HIV Programmes HIV programmes operate in environments where resources are often limited. An NGO may have: A limited number of community health workers A fixed outreach budget Limited HIV testing supplies Limi
AI 资讯
Union-Find: The Fellowship of the Sets
The Quest Begins (The "Why") I still remember the first time I saw LeetCode 323 “Number of Connected Components in an Undirected Graph”. I stared at the adjacency list, thought “I’ll just run a DFS from every node”, and coded it up in ten minutes. The solution passed the easy tests, but when the hidden test cases hit a graph with 10⁵ nodes and 10⁵ edges, my DFS started to choke—stack overflows, repeated visits, and a sinking feeling that I was brute‑forcing a problem that deserved a smarter tool. That night, after a few too many coffees, I stumbled upon a tiny comment in a discussion thread: “Union‑Find can do this in almost O(1) per operation”. My curiosity sparked like a power‑up in a retro arcade game. I had to know why this seemingly simple data structure could turn a nightmare into a breeze. The Revelation (The Insight) At its heart, Union‑Find (aka Disjoint Set Union, DSU) maintains a collection of elements partitioned into disjoint subsets. It supports two operations: Find(x) – returns the representative (root) of the set containing x . Union(x, y) – merges the sets containing x and y . The magic lies in two simple heuristics: Path Compression – when we walk up the tree to find a root, we make every node on that path point directly to the root. Future finds become flat, almost constant‑time. Union by Rank/Size – we always attach the smaller tree under the root of the larger one, keeping the overall tree shallow. Why does this give us near‑O(1) amortized time? Think of each Find as paying a small “tax” to flatten the path. The tax is paid only a few times per node before it becomes a direct child of the root. Over a sequence of m operations, the total work is bounded by O(m α(n)) , where α is the inverse Ackermann function—so slow‑growing it’s practically a constant for any realistic n . In plain English: every time we climb up, we leave a shortcut behind. The next climber benefits from that shortcut, and the structure keeps getting better. It’s like building
开发者
How Many Introductions Away Are You From Pedro Pascal? A Practical Introduction to Graph Search
I was watching The Mandalorian the other day when it struck me that I don't know Pedro Pascal, which...
AI 资讯
How to Test Search Relevance Before You Ship a Ranking Change
You can load-test search latency with a script and a graph. Relevance has no such gauge by default, so most teams ship a new ranking rule, eyeball a handful of queries, and hope nothing important regressed. The fix is a small, boring relevance test suite: a fixed set of queries, human-judged expected results, and a metric you compute the same way every time — so "did this ranking change help?" becomes a number you can diff, not an argument you have in Slack. This post is a build guide. By the end you'll have a judgments file, a scorer that outputs precision@k, MRR, and nDCG, and a before/after comparison you can wire into CI. The examples use Postgres full-text search, but the harness is engine-agnostic — Elasticsearch, Meilisearch, or a vector store all slot into the same shape. Why can't I just load-test relevance the way I load-test latency? Latency is a property of the system. Relevance is a property of the match between a query and what a human expected to see — and that judgment lives outside the database. A commenter on an earlier post about running Postgres search in production put it well: latency can be load-tested, but quality needs query sets, expected result buckets, bad-query examples, and a way to compare changes before shipping a new ranking rule. That's the whole job, and none of it comes for free with your index. The trap is thinking a passing query proves relevance. SELECT ... WHERE tsv @@ query returning rows tells you the index matched. It says nothing about whether the right rows landed in the top 5, which is all a user ever sees. The takeaway: relevance is measured against human judgments, not row counts — so the first artifact you build is the judgments, not the query. Building the golden query set Start with 20–50 real queries. Pull them from your search logs if you have them (the head terms plus a long tail of specific ones), or write them from real user intents if you don't. For each query, mark which documents should come back and how rel
AI 资讯
Data Scientist Learning JS: Promises and resolve()
Context: I'm a data scientist/analyst (in Python and R) learning development from scratch. Inevitably, I am learning these through the lens of what I already know. If you have a similar background and are a beginner developer, I hope these analogies help! Any comments, especially if you spot any misunderstanding, are appreciated. Commenting is caring <3 Motivation: I was building a mock data layer for a fitness social app — simulating what happens when users fetch new posts from a feed. The function needs to return mock posts after a delay, simulating a real network request. Working Code: `function fakeFetchPosts() { return new Promise((resolve) => { setTimeout(() => { resolve(posts); }, 2000); }); } async function main() { console.log("Fetching..."); const fetchedPosts = await fakeFetchPosts(); console.log("Fetched posts:", fetchedPosts); } main(); console.log("Sync code ran");` What do you expect to see as an output? I first confused the logic with blocking. For example, in webscraping, something like time.sleep() or Selenium's WebDriverWait(driver, 10).until(EC.presence_of_element_located(...)) . In this case, output will be Fetching..., Fetched posts: ..., then Sync code ran. However, the output gives Fetching..., Sync code ran, and then Fetched posts. In the former, the whole script (single thread) pauses and does nothing else until the wait ends or the condition is met. The latter is different in that the rest of your program keeps running during the wait, and thus the output where Sync code ran is printed first before the fetchedPosts. By the way, posts are arrays. const posts = [{ author: "j1wonkim", text: "Testing Physical", likes: 100, }, {author: "onewc0218", text: "Love love", likes: 55, }, {author: "gakbca", text: "You are good", likes: 10, } ];
AI 资讯
The Matrix: Why Merge Sort Beats the Brute Force
The Quest Begins (The "Why") I still remember the first time I got hit with a sorting question in an interview. The interviewer slid a whiteboard marker across the table and said, “Sort this array of a million integers – and tell me why you chose your method.” My brain went straight to the trusty old bubble sort I’d learned in CS101. I started writing nested loops, feeling like Neo dodging bullets in slow motion, only to realize the runtime was creeping toward O(n²). After a few painful minutes, I could see the interviewer’s eyes glaze over – not because I was wrong, but because I was using a sledgehammer to crack a nut. That moment sparked a quest: What makes a sorting algorithm truly efficient, and how do I know when to reach for it? I dove into textbooks, blog posts, and late‑night YouTube deep dives. The answer kept pointing back to one algorithm that felt like discovering a hidden cheat code: Merge Sort . The Revelation (The Insight) So why does Merge Sort work so well? It’s not just about splitting and merging; it’s about guaranteeing that each level of recursion does a linear amount of work, no matter how the input is arranged. Think of an unsorted array as a messy pile of LEGO bricks. Merge Sort first divides the pile into two halves, then halves again, until each sub‑pile contains a single brick – which is, by definition, sorted. The magic happens in the merge step: we take two already‑sorted sub‑arrays and walk through them with two pointers, always picking the smaller front element and appending it to the result. Because each sub‑array is sorted, we never need to look back; we simply advance one pointer at a time. That walk is O(n) for the merge: each element is examined exactly once as it gets placed into the output array. Since we split the array log₂ n times (each level halves the size), we perform an O(n) merge at each of those log₂ n levels. Multiply them together and you get O(n log n) worst‑case time, with O(n) extra space for the temporary buffer
AI 资讯
Your ORM is hiding the line that caused the slow query
I was building a runtime N+1 query detector for Node. The detection part worked on the first afternoon. Getting it to tell you which line of your code caused the problem took considerably longer, and taught me something about how ORMs execute queries that I had not thought about before. This is that story, and the fix. The symptom The detector instruments your database driver. When the same query shape runs many times inside one request, it reports it — along with the file and line that issued it, which is the part that actually saves you time: nplusone 1 finding in GET /orders — 51 queries, 840ms N+1 query 50× SELECT * FROM items WHERE order_id = ? at src/routes/orders.ts:47:38 (loadOrdersPage) 612ms spent here That worked. Then I pointed it at an app using Drizzle and got this instead: N + 1 query 12 × select "id" , "order_id" from "items" where "items" . "order_id" = $ 1 < unknown call site > Detected, counted, and attributed to nothing. Do not theorise. Dump the stack My first instinct was that my frame filter was too aggressive — it skips node_modules , node:internal , and the library's own frames, so maybe it was eating something it should not have. Rather than guess, I printed the whole stack at the exact moment the driver was called: const originalQuery = pg . Client . prototype . query ; pg . Client . prototype . query = function (... args ) { const previous = Error . stackTraceLimit ; Error . stackTraceLimit = 100 ; const stack = new Error (). stack . split ( " \n " ). slice ( 1 ); Error . stackTraceLimit = previous ; console . log ( " FRAMES: " , stack . length ); stack . forEach (( line , i ) => { const mine = ! /node_modules|node:internal/ . test ( line ); console . log ( ` ${ String ( i ). padStart ( 3 )} ${ mine ? " >>> " : " " } ${ line . trim ()} ` ); }); return originalQuery . apply ( this , args ); }; Here is what came back for a single await db.select().from(items).where(...) : FRAMES: 12 0 at Proxy.<anonymous> (.../nplusone/dist/adapters/postgre
AI 资讯
Stop context-switching to manage your distributed SQL infra
I remember the old days of manual scaling. You'd jump into a CLI, check your metrics, realize you needed another node or a capacity adjustment, log into a web console, navigate three layers deep into some proprietary dashboard, and hope you didn't click the wrong thing while trying to find a specific cluster ID. Now we have AI agents. But most people are using them wrong. They treat Claude or Cursor as just better search engines for code, rather than giving them hands. If you're running high-availability workloads on something like TiDB Cloud, the friction isn't in writing the SQL—you already know how to do that. The friction is in the operational visibility: knowing exactly what’s happening across your serverless instances versus your dedicated clusters without leaving your IDE. The Gap Between Code and Infrastructure The reason I spend so much time building things like MCPFusion is precisely because of this disconnect. An LLM might help you write a complex join perfectly, but if it doesn't know whether the target TiDB X instance is actually healthy or which project ID handles your staging environment, it's basically flying blind. You end up copy-pasting JSON blobs from your terminal into the chat window just to give the model context. That's slow, prone to error, and frankly, beneath what modern tooling should look like. This is why we released the TiDB Cloud (Serverless Distributed SQL) MCP server on Vinkius. It closes that loop. What This Actually Does (And Doesn't) Let's be very clear about what this tool allows you to do through an agent like Claude or Cursor. We aren't looking for "magic" here; we want predictable utility. The current implementation focuses on discovery and inspection. In DevOps terms, it provides a controlled read-only view of your topology. Here is what's available: Organization Discovery: You can call list_projects to see everything sitting under your umbrella and pull metadata via get_project . This solves the "what was that project ID ag
AI 资讯
dbt Semantic Layer vs Cube vs AtScale: Choosing an Enterprise Semantic Layer
Three semantic layers, three architectures, three very different bills. All three will define what a metric means. None of them proves an AI agent is allowed to run it. Quick orientation dbt Semantic Layer Cube AtScale Core idea Metrics as version-controlled code Headless API in front of metrics OLAP-style aggregate acceleration Strongest when You want engineering discipline Many apps consume the same numbers Heavy, stable aggregate workloads Modelling Hand-authored YAML Hand-authored data model Hand-authored cubes Cost driver Plan tier + query volume Pre-aggregation builds + compute Quote-based licence + compute Governance Upstream, in the warehouse In front of the API On the cube Each is competent at what it was built for. If your consumers are dashboards and analysts, any of the three will serve you. The question none of them answers An agent doesn't arrive with a metric name. It arrives with an intent in English and has to work out which entities, which grain, which joins, and whether it's entitled to any of it. That exposes two gaps every one of these shares: Undefined intent has no answer. Coverage is whatever someone remembered to model. Business questions don't respect that boundary. Authorisation is checked around the query, not inside it. A filter applied after execution means the data already moved. What to actually evaluate on Ignore feature matrices and score these five: Answer a question nobody modelled, on your schema Show why one join path was chosen over two others Same question, two users with different entitlements — show both SQL statements Ask something ambiguous. Refusal or guess? Reproduce a number from six months ago with the definitions then in force Most evaluations stop at 1. Numbers 3 and 5 are the ones that decide whether the thing ships in a regulated business. The full breakdown — architecture-by-architecture comparison, cost profiles, and the migration implications of each — is here: 👉 dbt Semantic Layer vs Cube vs AtScale: Choosing a