Respuestas del sorteo de la European FabCon + SQLCon 2026 Barcelona

Respuestas del sorteo de la European FabCon + SQLCon 2026 Barcelona: explicamos las 5 preguntas técnicas y por qué cada opción era correcta.

Hace unos días lanzamos en nuestra comunidad un sorteo muy especial. La organización de la European FabCon + SQLCon 2026 Barcelona nos regaló una entrada de tres días para sortear entre vosotros y decidimos que, ya que nos juntamos para hablar de datos, la entrada no iba a decidirse simplemente sacando un nombre de una urna virtual.

Había que responder correctamente cinco preguntas técnicas. Quienes acertaron las cinco entraron en el sorteo y ya tenemos ganadora: enhorabuena, Inés. Esperamos que disfrutes de los tres días de conferencia y, sobre todo, que vuelvas con unas cuantas ideas nuevas que poner a prueba.

También queremos agradecer a la organización de la European FabCon + SQLCon 2026 Barcelona que haya contado con nuestra comunidad y, por supuesto, a todos los que habéis participado. Las cinco preguntas tocaban búsqueda híbrida y RAG, SQL Database Projects y schema drift, Data API Builder con GraphQL, indexación de JSON y algo de manipulación de cadenas con T-SQL.

Ahora que el sorteo ha terminado podemos hacer la parte interesante, explicar las respuestas. Para ello voy a tirar de IA, es fin de semana y no me apetece trabajar más, lo siento. Pero, os prometo que la respuesta está validada y es correcta.

Pregunta 1: cómo combinar búsqueda vectorial y full-text sin mezclar puntuaciones incompatibles

La primera pregunta planteaba una aplicación RAG que recuperaba contexto mediante dos mecanismos: búsqueda full-text y búsqueda vectorial. Ambos devolvían resultados ordenados, pero sus puntuaciones utilizaban escalas completamente diferentes.

La respuesta correcta era A: combinar mediante Reciprocal Rank Fusion los rankings obtenidos mediante búsqueda vectorial y FREETEXTTABLE.

El detalle importante está en que Reciprocal Rank Fusion, o RRF, no necesita comparar directamente las puntuaciones originales. Trabaja con la posición que ocupa cada documento dentro de cada ranking.

Simplificando, cada posición aporta un valor parecido a:

Después sumamos las contribuciones de las distintas listas. Un documento situado muy arriba en la búsqueda vectorial y también bien colocado en full-text acumulará más puntuación que otro que solo destaque en una de ellas.

Eso resuelve precisamente el problema que planteábamos. Una distancia coseno, una similitud vectorial y el RANK producido por full-text no tienen por qué compartir significado ni distribución. Intentar sumar directamente esos valores sería comparar unidades que no representan lo mismo. RRF evita ese problema porque utiliza el orden relativo y no las puntuaciones en bruto. Microsoft describe precisamente RRF como un método score-free apropiado para fusionar búsquedas con distribuciones distintas, como BM25 y similitud vectorial.

¿Por qué FREETEXTTABLE y no CONTAINS? Porque FREETEXTTABLE devuelve KEY y RANK. En cambio, CONTAINS es un predicado: responde si una fila cumple o no la condición, pero no devuelve un ranking. CONTAINSTABLE sí lo haría, pero no era lo que decía la opción C.

La opción B, basada en percentiles y una media geométrica, podría formar parte de un sistema de scoring diseñado expresamente para un workload determinado, pero ya obliga a introducir una transformación y unas decisiones sobre las escalas. Justo lo que queríamos evitar.

La opción D tampoco fusiona realmente ambos rankings. Primero reduce el conjunto mediante vector search y después deja que full-text trabaje únicamente sobre esos candidatos. Un documento excelente léxicamente que haya quedado fuera del primer corte vectorial ya no tiene ninguna posibilidad de aparecer.

La clave era reconocer que teníamos dos rankings válidos, no dos puntuaciones directamente comparables.

Pregunta 2: detectar schema drift no significa borrar todo lo que no esté en el proyecto

La segunda pregunta trataba un problema bastante más operativo. Tenemos un SQL Database Project almacenado en GitHub y queremos detectar modificaciones realizadas directamente sobre producción. Sin embargo, hay objetos de producción gestionados por otros procesos y no queremos que cada despliegue los elimine alegremente.

La respuesta correcta era B: utilizar un DriftReport para detectar los cambios realizados fuera del proceso de despliegue y tratar ese control independientemente de DropObjectsNotInSource.

Aquí había que distinguir dos conceptos que se mezclan con demasiada facilidad: detectar diferencias y decidir qué hacer con ellas.

DriftReport informa de los cambios realizados en una base de datos registrada desde la última vez que se registró su estado. Es decir, nos proporciona un mecanismo para comprobar que aquello que creemos haber desplegado sigue correspondiéndose con la realidad de la base de datos. SqlPackage dispone además de BlockWhenDriftDetected, que permite impedir una actualización cuando detecta ese desfase.

DropObjectsNotInSource responde a otra pregunta. Indica si, durante la publicación, deben eliminarse del destino los objetos que no existen en el .dacpac. Microsoft lo documenta explícitamente como una propiedad de la operación de despliegue.

Por tanto, detectar drift no obliga a corregirlo automáticamente borrando objetos.

Ese era el problema de la opción A. Activar siempre DropObjectsNotInSource=True puede ser precisamente lo contrario de lo que necesitamos cuando existen objetos administrados fuera del proyecto. Una cosa es que el pipeline nos diga «producción ya no coincide con el estado registrado» y otra muy distinta responder «pues borremos todo lo que sobra». Automatizar una decisión equivocada solo consigue equivocarnos más deprisa.

La opción C también rompe el modelo. Si importamos producción antes de cada build y la convertimos automáticamente en nuestra fuente de verdad, los cambios manuales dejan de ser drift: acabamos incorporándolos al modelo. Git deja de definir el estado deseado y pasa a documentar lo que alguien haya decidido hacer en producción.

Y desactivar la validación del modelo, como proponía D, no soluciona absolutamente nada relacionado con el drift.

La lección es sencilla: observación y remediación deben ser decisiones separadas.

Pregunta 3: una FOREIGN KEY no define por sí sola el contrato GraphQL de Data API Builder

La tercera pregunta planteaba dos entidades, Customer y Order, expuestas mediante Data API Builder. Queríamos poder consultar un cliente y navegar desde GraphQL hasta sus pedidos.

La respuesta correcta era C: configurar las entidades y la relación que DAB va a exponer mediante GraphQL.

Aquí la trampa estaba en confundir el modelo relacional de la base de datos con el contrato de la API.

Una FOREIGN KEY describe una relación e impone integridad referencial en SQL. Data API Builder puede aprovechar esa información y, una vez que hemos definido una relación, incluso puede inferir los campos implicados cuando existe una clave foránea adecuada. Pero eso no significa que DAB publique automáticamente todas las relaciones que encuentre en la base de datos.

La documentación actual es bastante explícita: para poder navegar entre entidades hay que indicar a DAB cómo se relacionan mediante la sección relationships. La configuración establece, entre otras cosas, la entidad destino y la cardinalidad.

Ese matiz descarta la opción A. La FOREIGN KEY ayuda a implementar la relación, pero no sustituye su definición en la API.

La B falla por un motivo parecido. Exponer Customer no provoca que DAB descubra Order, la convierta mágicamente en otra entidad pública y modifique el esquema GraphQL durante la primera petición. Las entidades que DAB expone forman parte de su configuración.

La opción D se va al extremo contrario. No necesitamos crear obligatoriamente una vista con un JOIN. GraphQL en DAB permite modelar relaciones entre entidades y navegar por ellas, que era precisamente lo que pretendíamos hacer.

Esto además tiene una consecuencia arquitectónica importante. El esquema físico de la base de datos y la superficie que queremos publicar no son la misma cosa. No todas las relaciones existentes en SQL deberían convertirse automáticamente en navegación disponible para cualquier consumidor de una API. La configuración también forma parte de nuestra frontera de seguridad y de nuestro contrato externo.

La base de datos conoce las relaciones. La API decide cuáles expone.

Pregunta 4: cómo indexar una propiedad JSON en SQL Server 2022

La cuarta pregunta nos llevaba a SQL Server 2022. Una tabla contiene varios millones de filas y almacena JSON dentro de una columna nvarchar(max). La consulta filtra así:

Queremos que el motor pueda utilizar un índice.

La respuesta correcta era B: crear una columna calculada basada en JSON_VALUE y crear un índice sobre esa columna; no necesita ser PERSISTED necesariamente.

En SQL Server 2022 no podemos crear un índice directamente sobre una propiedad interna del documento JSON como hacemos en SQL Server 2025. La técnica documentada consiste en exponer esa propiedad mediante una columna calculada y construir sobre ella un índice convencional.

Por ejemplo, conceptualmente podríamos hacer:

Ahora viene uno de los detalles importantes de la pregunta: la columna calculada no tiene que ser PERSISTED para poder utilizar esta técnica. Microsoft muestra precisamente el ejemplo con una columna calculada no persistida. Además, si mantenemos en la consulta la misma expresión JSON_VALUE, el optimizador puede reconocer la equivalencia con la columna calculada y considerar su índice. No necesitamos obligatoriamente reescribir todas las consultas para hacer referencia al nombre de la nueva columna.

Eso descarta la C.

La A tampoco puede ser correcta porque estamos específicamente en SQL Server 2022. CREATE JSON INDEX pertenece a SQL Server 2025.

La D supone que un índice normal sobre Payload permite localizar una propiedad interna del JSON. No funciona así. Para un nvarchar(max), el índice no construye una estructura secundaria que conozca cada ruta JSON que guardamos dentro del texto.

Hay además un matiz de producción que el test no necesitaba para responder, pero sí deberíamos recordar. JSON_VALUE puede devolver nvarchar(4000), por lo que conviene estudiar el tipo y la longitud reales de la propiedad que vamos a indexar. Microsoft recomienda convertirla al tipo más pequeño apropiado cuando sea posible, porque una clave de índice innecesariamente grande tiene consecuencias de almacenamiento y puede llegar a provocar problemas en operaciones DML.

Y, como siempre, tener un índice disponible no significa que vaya a ser utilizado en todas las consultas. La selectividad, las columnas solicitadas y el coste de los posibles key lookups siguen formando parte de la decisión del optimizador.

El índice no deja de ser un índice porque haya JSON de por medio. Afortunadamente, tampoco adquiere poderes mágicos.

Pregunta 5: SUBSTRING, CHARINDEX y una pequeña trampa con las posiciones

La última pregunta parecía bastante más inocente:

Queríamos obtener:

La respuesta correcta era A.

Vamos a calcularlo porque aquí la diferencia entre las opciones era literalmente de un carácter.

LEN(@Email) devuelve 28. El carácter @ ocupa la posición 18, por lo que el dominio comienza en la posición 19.

Después necesitamos localizar el último punto. Una forma cómoda consiste en invertir la cadena:

En es.aserpme@..., el primer punto aparece en la posición 3. Por tanto, la longitud que queremos extraer es:

Empezamos en la posición 19 y extraemos siete caracteres:

Eso es exactamente lo que hace la opción A.

La opción B suma uno a la longitud y devuelve ocho caracteres, por lo que también captura el punto final: empresa..

La opción C comienza en la posición del propio @, no después de él. Ya hemos desplazado mal la extracción antes de empezar a discutir la longitud.

La D utiliza CHARINDEX('.', @Email) sobre la cadena original. El primer punto no es el que precede a es, sino el que aparece en roberto.carrancio. Por tanto, está utilizando una posición que pertenece al nombre de usuario para calcular dónde termina el dominio.

Esta pregunta tenía además una pequeña segunda lectura. La expresión resuelve el requisito concreto planteado, pero no deberíamos confundir este ejercicio de manipulación de cadenas con un parser universal de nombres de dominio. Direcciones con subdominios o sufijos como .co.uk requieren definir primero qué entendemos exactamente por «dominio» y «extensión».

Con cadenas también conviene acordar el requisito antes de perfeccionar el SUBSTRING. SQL Server todavía no adivina lo que queríamos decir.

Cinco respuestas y una misma idea: entender el comportamiento importa más que recordar la sintaxis

Las respuestas del sorteo de la European FabCon + SQLCon 2026 Barcelona eran, por tanto, A, B, C, B y A.

Pero ese resultado es la parte menos importante. Las cinco preguntas compartían una idea, muchas respuestas incorrectas eran técnicamente verosímiles si nos quedábamos solo con el nombre de una característica.

RRF no sirve porque «mezcle búsquedas», sino porque evita comparar scores incompatibles. DriftReport no es lo mismo que eliminar objetos no declarados. Una FOREIGN KEY no constituye automáticamente un contrato GraphQL. SQL Server 2022 puede indexar una expresión sobre JSON sin disponer todavía de CREATE JSON INDEX. Y una expresión con SUBSTRING funciona porque cuadran exactamente las posiciones, no porque tenga suficientes CHARINDEX como para intimidar al problema.

De nuevo, gracias a la organización de la European FabCon + SQLCon 2026 Barcelona por cedernos la entrada, gracias a todos los que habéis participado y enhorabuena a Ines por ganar el sorteo.

Nos quedamos con algo mejor que cinco letras correctas, el razonamiento que permite volver a responder cuando cambien la versión, el escenario o el enunciado. Y eso, a diferencia de memorizar un test, sí suele sobrevivir al siguiente cambio de producto.

Logo SoyDBA

Únete a la newsletter de SoyDBA

Regístrate gratis para no perderte ninguna novedad. Te avisaré de noticias y eventos importantes

¡No hacemos spam! Lee nuestra política de privacidad para obtener más información.

Publicado por Roberto Carrancio

Mi nombre es Roberto Carrancio y soy un DBA de SQL server con más de 10 años de experiencia en el sector. Soy el creador del blog soydba.es donde intento publicar varios artículos a la semana (de lunes a viernes que los fines de semana me gusta estar con mi gente y disfrutar de mi moto) Espero que disfrutes leyendo este blog tanto como yo disfruto escribiendo y que te sea de utilidad. Si tienes alguna sugerencia, pregunta o comentario, puedes dejarlo al final de cada entrada o enviarme un correo electrónico. Estaré encantado de leerte y responderte. ¡Gracias por tu visita! Mi principal interés es compartir mi conocimiento sobre bases de datos con todo el que quiera aprenderlo. Me parece un mundo tan apasionante como desconocido. Fuera de lo profesional me encanta la cocina, la moto y disfrutar de tomar una cervecita con amigos.

Deja una respuesta