1. ð ã¯ããã«
ååã¯ãåäœã®æ£ããã»ããžãã¯ã»å¯èªæ§ãã®èŠç¹ãåŠã³ãŸããã
ä»åã¯å°ãèžã¿èŸŒãã 2ã€ã®èŠç¹ã解説ããŸãã
ããã©ãŒãã³ã¹ïŒ ãåããã ãã§ãªããéãã»å¹çããåããã
ã»ãã¥ãªãã£ïŒ ãåããã ãã§ãªããå®å šã«åããã
AIã¯ãåãã³ãŒãããçæããã®ã¯åŸæã§ããããã®2ã€ã®èŠç¹ãæãèœã¡ãããšããããããŸããåå¿è ã®ãã¡ããæèããç¿æ £ãã€ããŠãããŸãããðª
2. â¡ èŠç¹â£ïŒããã©ãŒãã³ã¹
ããã©ãŒãã³ã¹ãšã¯ïŒ
ããã©ãŒãã³ã¹ïŒperformanceïŒãšã¯ïŒ
ã³ãŒãããã©ããããéãã»å¹çããåãããã®ããšã§ãã
å°ãªãããŒã¿ã§ã¯åé¡ãªãåããŠããŠããããŒã¿ãå¢ãããšçªç¶é ããªãããšããããŸãã
AIãçæããã³ãŒãã¯ãå°ãªãããŒã¿ã§åããããšãã¯åé¡ãªããã§ããæ¬çªç°å¢ã§å€§éã®ããŒã¿ãæ¥ããšãã«äžæ°ã«åé¡ã衚é¢åããããšããããŸãã
N+1åé¡ïŒæãããããããã©ãŒãã³ã¹ã®èœãšã穎
N+1åé¡ãšã¯ïŒ
ããŒã¿ããŒã¹ïŒããŒã¿ãä¿åããå ŽæïŒã«å¯ŸããŠãæ¬æ¥1åã§æžãåãåããããNåäœåã«ç¹°ãè¿ããŠããŸãåé¡ã§ããäŸïŒãŠãŒã¶ãŒã100人ãããšãã
ãå šãŠãŒã¶ãŒãååŸïŒ1åïŒãïŒãåãŠãŒã¶ãŒã®æ³šæãååŸïŒ100åïŒã
= åèš101åã®åãåãããçºç â é ãïŒ
| N+1åé¡ãã | N+1åé¡ãªã | |
|---|---|---|
| åãåããåæ° | 1 + NåïŒããŒã¿ãå¢ããã»ã©å¢å ïŒ | 1ã2åïŒããŒã¿ãå¢ããŠãå€ãããªãïŒ |
| é床ãžã®åœ±é¿ | ããŒã¿ãå¢ãããšæ¥æ¿ã«é ããªã | ããŒã¿ãå¢ããŠãé床ã¯å®å® |
| AIã®ã³ãŒã | ããçæãã | æèããŠæç€ºããªããšçæããªã |
â AIããããã¡ãªã³ãŒãïŒN+1åé¡ããïŒ
// ãŠãŒã¶ãŒäžèЧãååŸ
const users = await db.user.findMany();
// åãŠãŒã¶ãŒã®æ³šæãåå¥ã«ååŸïŒNåã®DBåãåãããçºçïŒïŒ
for (const user of users) {
user.orders = await db.order.findMany({
where: { userId: user.id }
});
}
â 人éãã¬ãã¥ãŒããŠä¿®æ£ããã³ãŒãïŒ1åã§ååŸïŒ
// ãŠãŒã¶ãŒãšæ³šæãäžåºŠã«ååŸïŒ1åã®DBåãåããã§å®çµïŒïŒ
const users = await db.user.findMany({
include: { orders: true }
});
ãã§ãã¯ã®ãã€ã³ãïŒ
ã«ãŒãã®äžã«ããŒã¿ããŒã¹ã®åãåãããå ¥ã£ãŠãããèŠæ³šæã
ããŸãšããŠ1åã§åããªããïŒããšèããŸãããã
èšç®éïŒããŒã¿ãå¢ãããšãã®ãéãããæèãã
èšç®éãšã¯ïŒ
ããŒã¿ã®éãå¢ãããšãã«ãåŠçãã©ããããå¢ããããè¡šãææšã§ãã
ãOèšæ³ïŒãªãŒããŒèšæ³ïŒãã§è¡šçŸããŸãããé£ããèããªããŠå€§äžå€«ã
ãããŒã¿ã2åã«ãªã£ããšããåŠçã2åã§æžããïŒ4åã«ãªããïŒã ã§èããŸãããã
| çš®é¡ | ããŒã¿ã2åã«ãªããš | å ·äœäŸ |
|---|---|---|
| çæ³ç | åŠçã2åã§æžã | ãªã¹ããé çªã«1åèŠãã ãã®åŠç |
| èŠæ³šæ | åŠçã4åã«ãªã | ãªã¹ãã®äžã§ãªã¹ããæ¢ãïŒäºéã«ãŒãïŒ |
| å±éº | åŠçãççºçã«å¢ãã | å šãã¿ãŒã³ã詊ãåŠç |
â AIããããã¡ãªã³ãŒãïŒäºéã«ãŒãã§é ãïŒ
// éè€ããå€ãèŠã€ããïŒäºéã«ãŒãïŒ
function findDuplicates(list: number[]): number[] {
const duplicates: number[] = [];
for (let i = 0; i < list.length; i++) {
for (let j = i + 1; j < list.length; j++) { // â ãããåé¡ïŒ
if (list[i] === list[j] && !duplicates.includes(list[i])) {
duplicates.push(list[i]);
}
}
}
return duplicates;
}
â 人éãã¬ãã¥ãŒããŠä¿®æ£ããã³ãŒãïŒ1åã®ã«ãŒãã§æžãïŒ
// Setã䜿ã£ãŠ1åã®ã«ãŒãã§éè€ãæ€åº
function findDuplicates(list: number[]): number[] {
const seen = new Set<number>();
const duplicates = new Set<number>();
for (const item of list) {
if (seen.has(item)) {
duplicates.add(item);
}
seen.add(item);
}
return Array.from(duplicates);
}
ã100åã®ã¢ã¯ã»ã¹ãæ¥ããã©ããªãïŒããšåããããç¿æ £ã倧åã
åã·ãªãŒãºã§ç޹ä»ãããã®åãããã¯ãããã©ãŒãã³ã¹ã®åé¡ãçºèŠããã®ã«æé©ã§ãã
äžå¿ èŠãªããŒã¿ååŸã確èªãã
AIã¯ããšããããå šéšåããã³ãŒããæžããã¡ã§ãã
| åé¡ã®ãããã¿ãŒã³ | å ·äœäŸ | æ¹åç |
|---|---|---|
| å šã«ã©ã ãååŸããŠãã |
SELECT * ã§å
šåååŸ |
å¿ èŠãªã«ã©ã ã ãæå®ãã |
| å šä»¶ååŸããŠãã | ããŒãžã³ã°ãªãã§å šããŒã¿ååŸ |
limit ã offset ã§ä»¶æ°ãçµã |
| äžèŠãªããŒã¿ãå«ããŠãã | 䜿ããªããªã¬ãŒã·ã§ã³ãŸã§ååŸ | å¿
èŠãªãã®ã ã include ãã |
3. ð èŠç¹â€ïŒã»ãã¥ãªãã£
ãªãAIã®ã³ãŒãã¯ã»ãã¥ãªãã£ã匱ãããšãããã®ã
AIã¯ãåãã³ãŒãããåªå ããŠçæããããã
ã»ãã¥ãªãã£äžã®èæ ®ãåŸåãã«ãªããããã§ãã
ãŸãããããžã§ã¯ãåºæã®ã»ãã¥ãªãã£èŠä»¶ãç¥ããªãããã
ãäžè¬çã«åãã³ãŒããã¯æžããŠããå®å šãªã³ãŒããã¯æžããªãããšããããŸãã
| AIãèŠèœãšããããã»ãã¥ãªãã£ã®åé¡ | ãªã¹ã¯ |
|---|---|
| å ¥åå€ã®ããªããŒã·ã§ã³ãäžåå | äžæ£ãªããŒã¿ãåŠçããã |
| ãšã©ãŒã¡ãã»ãŒãžã«è©³çްæ å ±ãå«ãŸãã | æ»æè ã«ã·ã¹ãã æ å ±ãæŒãã |
| èªèšŒã»èªå¯ã®ãã§ãã¯ãæŒãã | æš©éã®ãªããŠãŒã¶ãŒãããŒã¿ã«ã¢ã¯ã»ã¹ã§ãã |
| ã·ãŒã¯ã¬ããæ å ±ãã³ãŒãã«å«ãŸãã | APIããŒããã¹ã¯ãŒããæµåºãã |
| å€ãã»è匱ãªã©ã€ãã©ãªã䜿ã | æ¢ç¥ã®æ»æææ³ã§äŸµå ¥ããã |
å ¥åå€ã®ããªããŒã·ã§ã³
ããªããŒã·ã§ã³ïŒvalidationïŒãšã¯ïŒ
ãå ¥åãããããŒã¿ãæ£ãã圢åŒãã©ãã確èªããããšãã§ãã
äŸïŒã¡ãŒã«ã¢ãã¬ã¹ã®åœ¢åŒãã§ãã¯ã»æ°å€ã®ç¯å²ãã§ãã¯ãªã©ã
ãŠãŒã¶ãŒããã®å ¥åã¯ãå¿ ãæªæããå€ãæ¥ãåæãã§ãã§ãã¯ããŸãã
â AIããããã¡ãªã³ãŒãïŒããªããŒã·ã§ã³ãªãïŒ
// ãŠãŒã¶ãŒã®å¹Žéœ¢ãæŽæ°ãã
async function updateAge(userId: string, age: number) {
await db.user.update({
where: { id: userId },
data: { age } // ageã-1ã§ã999ã§ãä¿åã§ããŠããŸãïŒ
});
}
â 人éãã¬ãã¥ãŒããŠä¿®æ£ããã³ãŒã
async function updateAge(userId: string, age: number) {
// 幎霢ã®ç¯å²ãã§ãã¯
if (!Number.isInteger(age) || age < 0 || age > 150) {
throw new Error("幎霢ã¯0ã150ã®æŽæ°ã§å
¥åããŠãã ãã");
}
await db.user.update({
where: { id: userId },
data: { age }
});
}
èªèšŒã»èªå¯ã®ç¢ºèª
èªèšŒïŒauthenticationïŒãšã¯ïŒ ãããªãã¯èª°ã§ããïŒãã確èªããããšïŒãã°ã€ã³ïŒ
èªå¯ïŒauthorizationïŒãšã¯ïŒ ãããªãã¯äœãã§ããŸããïŒãã確èªããããšïŒæš©éãã§ãã¯ïŒ
AIã¯APIã®ãšã³ããã€ã³ããå®è£ ãããšããèªå¯ãã§ãã¯ãå¿ããããšããããŸãã
â AIããããã¡ãªã³ãŒãïŒèªå¯ãã§ãã¯æŒãïŒ
// ãŠãŒã¶ãŒã®ãããã£ãŒã«ãååŸããAPI
async function getProfile(targetUserId: string) {
// 誰ã§ãä»äººã®ãããã£ãŒã«ãåããŠããŸãïŒ
return await db.user.findUnique({
where: { id: targetUserId }
});
}
â 人éãã¬ãã¥ãŒããŠä¿®æ£ããã³ãŒã
async function getProfile(
currentUserId: string, // ãã°ã€ã³äžã®ãŠãŒã¶ãŒ
targetUserId: string // ååŸããããŠãŒã¶ãŒ
) {
// èªåã®ãããã£ãŒã«ãã管çè
ã®ã¿ã¢ã¯ã»ã¹å¯èœ
const currentUser = await db.user.findUnique({
where: { id: currentUserId }
});
if (currentUserId !== targetUserId && currentUser?.role !== "admin") {
throw new Error("ãã®ãããã£ãŒã«ã«ã¢ã¯ã»ã¹ããæš©éããããŸãã");
}
return await db.user.findUnique({
where: { id: targetUserId }
});
}
ã·ãŒã¯ã¬ããæ å ±ã®ç®¡ç
ã·ãŒã¯ã¬ããæ å ±ãšã¯ïŒ
APIããŒã»ãã¹ã¯ãŒãã»ããŒã¿ããŒã¹ã®æ¥ç¶æ å ±ãªã©ã
å€éšã«æŒããŠã¯ãããªãç§å¯ã®æ å ±ã®ããšã§ãã
| â ãã£ãŠã¯ãããªãããš | â æ£ããæ¹æ³ |
|---|---|
| ã³ãŒãã«APIããŒãçŽæžã | ç°å¢å€æ°ïŒ.envïŒã«ä¿åãã |
| ãã¹ã¯ãŒãããã®ãŸãŸä¿å | ããã·ã¥åããŠä¿åãã |
.env ãGitã«ã³ããã |
.gitignore ã«è¿œå ããŠé€å€ãã |
| ãã°ã«ãã¹ã¯ãŒããåºå | ã»ã³ã·ãã£ããªæ å ±ã¯ãã°ã«å«ããªã |
â 絶察ã«ãã£ãŠã¯ãããªãã³ãŒã
// APIããŒãã³ãŒãã«çŽæžãïŒGitã«ã³ãããããããšäžçäžã«å
¬éãããïŒïŒ
const apiKey = "sk-1234567890abcdef";
â æ£ããã³ãŒã
// ç°å¢å€æ°ããååŸãã
const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error("API_KEYãèšå®ãããŠããŸãã");
}
CVEãšã©ã€ãã©ãªã®è匱æ§ãã§ãã¯
CVEïŒCommon Vulnerabilities and ExposuresïŒãšã¯ïŒ
äžçäžã§çºèŠãããã»ãã¥ãªãã£ã®è匱æ§ïŒåŒ±ç¹ïŒã«ä»ããããçªå·ã§ãã
äŸïŒCVE-2021-44228ïŒLog4Shellãšããæåãªè匱æ§ïŒAIã¯å€ãããŒãžã§ã³ã®ã©ã€ãã©ãªã䜿ã£ãã³ãŒããçæããããšããããŸãã
å€ãã©ã€ãã©ãªã«ã¯æ¢ç¥ã®è匱æ§ãå«ãŸããŠããããšãããã®ã§æ³šæãå¿ èŠã§ãã
| ãã§ãã¯æ¹æ³ | ã³ãã³ãã»æ¹æ³ |
|---|---|
| Node.jsã®è匱æ§ãã§ã㯠|
npm audit ãã¿ãŒããã«ã§å®è¡ |
| Pythonã®è匱æ§ãã§ã㯠|
pip audit ãã¿ãŒããã«ã§å®è¡ |
| GitHubã®èªåãã§ã㯠| Dependabotãæå¹ã«ãã |
| æåç¢ºèª | NVDïŒhttps://nvd.nist.govïŒã§CVEãæ€çŽ¢ |
AIã«ã©ã€ãã©ãªã®ããŒãžã§ã³ã確èªãããããã³ããäŸïŒ
ããã®ã³ãŒãã§äœ¿ã£ãŠããã©ã€ãã©ãªã«æ¢ç¥ã®è匱æ§ã¯ãããŸããïŒ
ææ°ã®å®å®ããŒãžã§ã³ã䜿ã£ãŠããã確èªããŠãã ããã
4. ð ã¬ãã¥ãŒãã§ãã¯ãªã¹ãïŒç¬¬äºåãŸãšãïŒ
â¡ ããã©ãŒãã³ã¹
- ã«ãŒãã®äžã«ããŒã¿ããŒã¹ã®åãåãããå ¥ã£ãŠããªãïŒN+1åé¡ïŒ
- äºéã«ãŒããªã©ãããŒã¿ãå¢ãããšé ããªãåŠçããªã
-
å¿
èŠãªããŒã¿ã ãååŸããŠããïŒ
SELECT *ã䜿ã£ãŠããªãïŒ - 倧éããŒã¿ãäžåºŠã«ååŸããŠããªãïŒããŒãžã³ã°ãå¿ èŠãªå Žæã«ããïŒ
- ã100åã®ã¢ã¯ã»ã¹ãæ¥ããïŒããšèããŠåé¡ããªã
ð ã»ãã¥ãªãã£
- ãŠãŒã¶ãŒããã®å ¥åå€ã«ããªããŒã·ã§ã³ããã
- èªå¯ãã§ãã¯ãæŒããŠããªãïŒèª°ã§ãã¢ã¯ã»ã¹ã§ããç¶æ ã«ãªã£ãŠããªãïŒ
- APIããŒã»ãã¹ã¯ãŒããã³ãŒãã«çŽæžããããŠããªã
-
.envãã¡ã€ã«ã.gitignoreã«è¿œå ãããŠãã -
䜿çšããŠããã©ã€ãã©ãªã«æ¢ç¥ã®è匱æ§ããªãïŒ
npm auditçã§ç¢ºèªïŒ - ãšã©ãŒã¡ãã»ãŒãžã«å éšæ å ±ãå«ãŸããŠããªã
5. ð¯ ãŸãšã
| èŠç¹ | äžèšã§èšããš | ããããAIã®èœãšã穎 |
|---|---|---|
| â¡ ããã©ãŒãã³ã¹ | éãã»å¹çããåãã | N+1åé¡ã»äºéã«ãŒãã»å šä»¶ååŸ |
| ð ã»ãã¥ãªã㣠| å®å šã«åãã | ããªããŒã·ã§ã³äžè¶³ã»èªå¯æŒãã»ã·ãŒã¯ã¬ããçŽæžã |
AIã¯ãåãã³ãŒãããçæããã®ãåŸæã
ãéãã³ãŒãããå®å šãªã³ãŒããã«ããã®ã¯äººéã®ä»äºãããã©ãŒãã³ã¹ãšã»ãã¥ãªãã£ã¯ãåŸããçŽãã°ãããã§ã¯ãªãã
æåããæèããããšã倧åã§ãã
ã¬ãã¥ãŒæã®ãã§ãã¯ãªã¹ããæŽ»çšããŠãç¿æ £ã«ããŠãããŸãããðª
次åã¯èšèšã»ã¢ãŒããã¯ãã£ã®èŠç¹ã解説ããŸãïŒ
ãåãã»éãã»å®å
šãã®æ¬¡ã®ã¬ãã«ããé·ã䜿ããã³ãŒãããäœãããã®èŠç¹ãåŠã³ãŸãð
ð¬ 質åãææ³ãããã°ãã³ã¡ã³ãæ¬ã§ãæ°è»œã«ã©ãã!
ð 圹ã«ç«ã£ãããããã&ã¹ããã¯ããé¡ãããŸã!
ð ãããŸã§èªãã§ãã ãã£ãŠãæ¬åœã«ããããšãããããŸãã!
ð ã·ãªãŒãºèšäº
- ã第äžåãåäœã»ããžãã¯ã»å¯èªæ§ã®èŠç¹
- ã第äºåãããã©ãŒãã³ã¹ã»ã»ãã¥ãªãã£ã®èŠç¹ïŒãã®èšäºïŒ
- ã第äžåãèšèšã»ã¢ãŒããã¯ãã£ã®èŠç¹ïŒè¿æ¥å ¬éïŒ